{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Add Without Plus LCCI"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Easy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #LCCI"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #bit-manipulation #math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #位运算 #数学"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: add"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #不用加号的加法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>设计一个函数把两个数字相加。不得使用 + 或者其他算术运算符。</p>\n",
    "\n",
    "<p><strong>示例:</strong></p>\n",
    "\n",
    "<pre><strong>输入:</strong> a = 1, b = 1\n",
    "<strong>输出:</strong> 2</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>a</code>,&nbsp;<code>b</code>&nbsp;均可能是负数或 0</li>\n",
    "\t<li>结果不会溢出 32 位整数</li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [add-without-plus-lcci](https://leetcode.cn/problems/add-without-plus-lcci/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [add-without-plus-lcci](https://leetcode.cn/problems/add-without-plus-lcci/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, matrix):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        Q = []\n",
    "        visited = set()\n",
    "        \n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if matrix[i][j] == 0:\n",
    "                    Q.append((i, j))\n",
    "                    visited.add((i, j))\n",
    "        \n",
    "        while Q:\n",
    "            i, j = Q.pop(0)\n",
    "            for x, y in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:\n",
    "                if 0 <= x < m and 0 <= y < n and (x, y) not in visited:\n",
    "                    matrix[x][y] = matrix[i][j] + 1\n",
    "                    visited.add((x, y))\n",
    "                    Q.append((x, y))\n",
    "        return matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, matrix: 'List[List[int]]') -> 'List[List[int]]':\n",
    "        m = len(matrix)\n",
    "        if m == 0:\n",
    "            return []\n",
    "        n = len(matrix[0])\n",
    "        if n == 0:\n",
    "            return []\n",
    "\n",
    "        def BFS(matrix, i, j):\n",
    "            distance = 0\n",
    "            visit, queue = {(i, j)}, deque([(i, j)])\n",
    "            while queue:\n",
    "                size = len(queue)\n",
    "                for _ in range(size):\n",
    "                    x, y = queue.popleft()\n",
    "                    if 0 <= x < m and 0 <= y < n:\n",
    "                        if matrix[x][y] == 0:\n",
    "                            ans[i][j] = distance\n",
    "                            return\n",
    "                        visit.add((x, y))\n",
    "                        queue.extend([\n",
    "                            (x - 1, y), (x + 1, y),\n",
    "                            (x, y - 1), (x, y + 1)\n",
    "                        ])\n",
    "                distance += 1\n",
    "\n",
    "        ans = [[0 for _ in range(n)] for _ in range(m)]\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if matrix[i][j] == 0:\n",
    "                    continue\n",
    "                BFS(matrix, i, j)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, matrix):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        m,n = len(matrix),len(matrix[0])\n",
    "        Q = collections.deque([])\n",
    "        visited = set()\n",
    "        \n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if matrix[i][j] == 0:\n",
    "                    Q.append((i,j))\n",
    "                    visited.add((i,j))\n",
    "        while Q :\n",
    "            i,j = Q.popleft()\n",
    "            for x,y in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n",
    "                if 0 <= x < m and 0<= y <n and (x,y) not in visited:\n",
    "                    matrix[x][y] = matrix[i][j] + 1\n",
    "                    visited.add((x,y))\n",
    "                    Q.append((x,y))\n",
    "        return matrix\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# https://leetcode-cn.com/problems/01-matrix/description/\n",
    "from queue import PriorityQueue\n",
    "\n",
    "\n",
    "class Node(object):\n",
    "    position = None\n",
    "    weight = None\n",
    "\n",
    "    def __init__(self, position, weight):\n",
    "        self.position = position\n",
    "        self.weight = weight\n",
    "\n",
    "    def __lt__(self, other):\n",
    "        return self.weight < other.weight\n",
    "\n",
    "    def __eq__(self, other):\n",
    "        return self.weight == other.weight\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, matrix):\n",
    "        \"\"\"\n",
    "        :type matrix: List[List[int]]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "\n",
    "        if not matrix or not matrix[0]:\n",
    "            return matrix\n",
    "\n",
    "        marked = set()\n",
    "        pQueue = PriorityQueue()\n",
    "\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "\n",
    "        for i, row in enumerate(matrix):\n",
    "            for j, val in enumerate(row):\n",
    "                if val == 0:\n",
    "                    pQueue.put(Node((i, j), 0))\n",
    "                else:\n",
    "                    matrix[i][j] = float('+inf')\n",
    "\n",
    "        while not pQueue.empty():\n",
    "            node = pQueue.get()\n",
    "            position = node.position\n",
    "            if position in marked:\n",
    "                continue\n",
    "            marked.add(position)\n",
    "\n",
    "            weight = node.weight\n",
    "            positions = [(position[0] - 1, position[1]),\n",
    "                         (position[0] + 1, position[1]),\n",
    "                         (position[0], position[1] - 1),\n",
    "                         (position[0], position[1] + 1)]\n",
    "            positions = [position for position in positions if 0 <= position[0] < m and 0 <= position[1] < n]\n",
    "\n",
    "            for p in positions:\n",
    "                if p in marked:\n",
    "                    continue\n",
    "\n",
    "                if weight + 1 < matrix[p[0]][p[1]]:\n",
    "                    matrix[p[0]][p[1]] = weight + 1\n",
    "                pQueue.put(Node(p, matrix[p[0]][p[1]]))\n",
    "\n",
    "        return matrix\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:\n",
    "        from collections import deque\n",
    "        m=len(matrix)\n",
    "        n=len(matrix[0])\n",
    "        directions=[(-1,0),(1,0),(0,1),(0,-1)]\n",
    "        \n",
    "        res=matrix\n",
    "\n",
    "        def Is(x,y):\n",
    "            return x>=0 and x<m and y>=0 and y<n\n",
    "\n",
    "        def bfs(x,y):\n",
    "            queue=deque([(x,y,0)])\n",
    "            visited=set([(x,y)])\n",
    "            while queue:\n",
    "                i,j,dis=queue.popleft()\n",
    "                for direction in directions:\n",
    "                    new_i,new_j=i+direction[0],j+direction[1]\n",
    "                    if Is(new_i,new_j) and (new_i,new_j) not in visited:\n",
    "                        visited.add((new_i,new_j))\n",
    "                        if matrix[new_i][new_j]==0:\n",
    "                            return dis+1\n",
    "                        queue.append((new_i,new_j,dis+1))\n",
    "\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if res[i][j]==1:\n",
    "                    res[i][j]=bfs(i,j)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        \"\"\"\n",
    "        每个0向四周扩散 进行BFS搜索\n",
    "        \"\"\"\n",
    "        m,n = len(mat),len(mat[0])\n",
    "        seen = set()\n",
    "        queue = deque()\n",
    "        dirs = [(0,-1),(0,1),(1,0),(-1,0)]\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j]==0:\n",
    "                    queue.append((i,j))\n",
    "                    seen.add((i,j))\n",
    "                    mat[i][j] = 2\n",
    "        while queue:\n",
    "            for i in range(len(queue)):\n",
    "                x,y = queue.popleft()\n",
    "                for dx,dy in dirs:\n",
    "                    new_x,new_y = x+dx,y+dy\n",
    "                    if 0<=new_x<m and 0<=new_y<n and (new_x,new_y) not in seen:\n",
    "                        mat[new_x][new_y] = mat[x][y]+1\n",
    "                        queue.append((new_x,new_y))\n",
    "                        seen.add((new_x,new_y))\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                mat[i][j] -= 2\n",
    "        return mat\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        # def bfs(q, visited, step):\n",
    "        #     while q:\n",
    "        #         size = len(q)\n",
    "        #         for _ in range(size):\n",
    "        #             x, y = q.popleft()\n",
    "        #             for nx, ny in ((x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)):\n",
    "        #                 if nx < 0 or nx >= m or ny < 0 or ny >= n:\n",
    "        #                     continue\n",
    "        #                 if mat[nx][ny] == 0:\n",
    "        #                     return step\n",
    "        #                 if (nx, ny) not in visited:\n",
    "        #                     q.append((nx, ny))\n",
    "        #                     visited.add((nx, ny))       \n",
    "        #         step += 1\n",
    "\n",
    "        # m, n = len(mat), len(mat[0])\n",
    "        # ans = [[-1] * n for _ in range(m)]\n",
    "        \n",
    "        # for i in range(m):\n",
    "        #     for j in range(n):\n",
    "        #         ans[i][j] += 1\n",
    "        #         if mat[i][j] == 1:\n",
    "        #             q = deque()\n",
    "        #             visited = set()\n",
    "        #             q.append((i, j))\n",
    "        #             visited.add((i, j))\n",
    "                    \n",
    "        #             ans[i][j] = bfs(q, visited, 1)\n",
    "\n",
    "        # return ans\n",
    "\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        queue = deque()\n",
    "        visited = [[0] * n for _ in range(m)]\n",
    "        res = [[0] * n for _ in range(m)]\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    queue.append((i, j))\n",
    "                    visited[i][j] = 1\n",
    "\n",
    "        step = 0\n",
    "        while queue:\n",
    "            size = len(queue)\n",
    "            for i in range(size):\n",
    "                x, y = queue.popleft()\n",
    "                if mat[x][y] == 1:\n",
    "                    res[x][y] = step\n",
    "                for nx, ny in ((x - 1, y), (x, y + 1), (x + 1, y), (x, y - 1)):\n",
    "                    if nx < 0 or nx >= m or ny < 0 or ny >= n or visited[nx][ny] == 1:\n",
    "                        continue\n",
    "                    queue.append((nx, ny))\n",
    "                    visited[nx][ny] = 1\n",
    "            step += 1\n",
    "\n",
    "        return res\n",
    "\n",
    "        \n",
    "\n",
    "                    \n",
    "                            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "  ### 多源最短路问题思路比较固定，大概分为以下几步： 1，设目标数组和标记数组，标记该点是否被访问到 2，寻找一开始的“源\",放入队列，并且标记已经访问过 2.当队列非空的时候，每次找队头元素，（记得弹出队列）四个方向（有时候是 八个方向）广搜，先判断是否超出边界或者被访问过，如果没有就把该点标记为访问过，按照题目要求要处理一下（这里是标记距离），然后放入队列即可\n",
    "class Solution:\n",
    "    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        dist = [[0] * n for _ in range(m)]\n",
    "        zeroes_pos = [(i, j) for i in range(m) for j in range(n) if matrix[i][j] == 0]\n",
    "        # 将所有的 0的下标 添加进初始队列中\n",
    "        q = collections.deque(zeroes_pos)\n",
    "        seen = set(zeroes_pos)\n",
    "\n",
    "        # 广度优先搜索\n",
    "        while q:\n",
    "            i, j = q.popleft()\n",
    "            for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:### 该点四个方向搜索\n",
    "                if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen: ### 这些是没有处理过的1\n",
    "                    dist[ni][nj] = dist[i][j] + 1\n",
    "                    q.append((ni, nj)) ### 添加进来，准备在他周围继续搜索，\n",
    "                    ### 第一遍，所有的在0附近的1都搞完了\n",
    "                    ###继续pop，就会找到新的pop\n",
    "                    seen.add((ni, nj)) ### 已经处理过了\n",
    "        \n",
    "        return dist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        n = len(finalCnt) + 1\n",
    "        g = [[] for _ in range(n)]  # 建图\n",
    "        for u, v in edges:\n",
    "            g[u].append(v)\n",
    "            g[v].append(u)\n",
    "\n",
    "        # final count of all n vertices\n",
    "        # initialize the final count of vertice 0 as complex number 1j\n",
    "        cnt = [0+1j] + finalCnt\n",
    "\n",
    "        # reverse simulation\n",
    "        for num, idx in plans[::-1]:\n",
    "            # option1: halve the number of volunteers\n",
    "            if num == 1:\n",
    "                cnt[idx] *= 2\n",
    "            # option2: adding the number of volunteers\n",
    "            elif num == 2:\n",
    "                for neighbor in g[idx]:\n",
    "                    cnt[neighbor] -= cnt[idx]\n",
    "            # option3: substracting the number of volunteers\n",
    "            else:\n",
    "                for neighbor in g[idx]:\n",
    "                    cnt[neighbor] += cnt[idx]\n",
    "        \n",
    "        s = sum(cnt)\n",
    "\n",
    "        # initial number of volunteers at vertex 0\n",
    "        initial0 = (totalNum - s.real) // s.imag\n",
    "\n",
    "        # final number of volunteers at each vertex\n",
    "        ans = [int(x.real + x.imag * initial0) for x in cnt]\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        # x , 1, 16 ---------- f(x) = 21\n",
    "        # 2*x-(1+x) , 1+x,16-(1+x)-----x+15==21\n",
    "        # 多项式系数?\n",
    "        # (1,0) (0,1) (0,16)\n",
    "        # 3:对附近的加上自身 2:对附近的减去自身 1:使自身翻倍\n",
    "        # finalCnt----(1,0) (0, finalCnt[0]) ... (0, finalCnt[-1])\n",
    "        d=defaultdict(set)\n",
    "        start=[(1,0)]+[(0,c) for c in finalCnt]\n",
    "        for x,y in edges:\n",
    "            d[x].add(y)\n",
    "            d[y].add(x)\n",
    "        for op, idx in reversed(plans):\n",
    "            if op==1:\n",
    "                start[idx]=tuple([2*c for c in start[idx]])\n",
    "            if op==2:\n",
    "                for p in d[idx]:\n",
    "                    start[p]=tuple([start[p][i]-start[idx][i] for i in range(2)])\n",
    "            if op==3:\n",
    "                for p in d[idx]:\n",
    "                    start[p]=tuple([start[p][i]+start[idx][i] for i in range(2)])\n",
    "        s=(0,0)\n",
    "        for p in start:\n",
    "            s=tuple([s[i]+p[i] for i in range(2)])\n",
    "        xx = (totalNum - s[1])//s[0]\n",
    "        return [c[0]*xx+c[1] for c in start]\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def volunteerDeployment(self, finalCnt: List[int], totalNum: int, edges: List[List[int]], plans: List[List[int]]) -> List[int]:\n",
    "        # x , 1, 16 ---------- f(x) = 21\n",
    "        # 2*x-(1+x) , 1+x,16-(1+x)-----x+15==21\n",
    "        # 多项式系数?\n",
    "        # (1,0) (0,1) (0,16)\n",
    "        # 3:对附近的加上自身 2:对附近的减去自身 1:使自身翻倍\n",
    "        # finalCnt----(1,0) (0, finalCnt[0]) ... (0, finalCnt[-1])\n",
    "        d=defaultdict(set)\n",
    "        start=[(1,0)]+[(0,c) for c in finalCnt]\n",
    "        for x,y in edges:\n",
    "            d[x].add(y)\n",
    "            d[y].add(x)\n",
    "        for op, idx in reversed(plans):\n",
    "            if op==1:\n",
    "                start[idx]=tuple([2*c for c in start[idx]])\n",
    "            if op==2:\n",
    "                for p in d[idx]:\n",
    "                    start[p]=tuple([start[p][i]-start[idx][i] for i in range(2)])\n",
    "            if op==3:\n",
    "                for p in d[idx]:\n",
    "                    start[p]=tuple([start[p][i]+start[idx][i] for i in range(2)])\n",
    "        s=(0,0)\n",
    "        for p in start:\n",
    "            s=tuple([s[i]+p[i] for i in range(2)])\n",
    "        xx = (totalNum - s[1])//s[0]\n",
    "        return [c[0]*xx+c[1] for c in start]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def relativeSortArray(self, arr1: List[int], arr2: List[int]) -> List[int]:\n",
    "        ct=dict()\n",
    "        notins=set()\n",
    "        arr2set=set(arr2)\n",
    "        for i in arr1:\n",
    "            if i in ct:ct[i]+=1\n",
    "            else:ct[i]=1\n",
    "            if i not in arr2set:\n",
    "                notins.add(i )\n",
    "        ans=[]\n",
    "        for i in arr2:\n",
    "            ans=ans+[i]*ct[i]\n",
    "        notinlt=list(notins)\n",
    "        notinlt.sort()\n",
    "        for i in notinlt:\n",
    "            ans=ans+[i]*ct[i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minPathSum(self, grid: List[List[int]]) -> int:\n",
    "\n",
    "        # 这是一个图的遍历问题\n",
    "        # 我们知道了一个完全连接图\n",
    "        # 节点数字有n_nods = len(grid)\n",
    "        # 如果当前要求节点i到节点j的最短路径，\n",
    "        # 用min_distances来存储当前从左上角到其余各个节点的最短路径\n",
    "        # min_distances[j] = min([min_distances[j], min_distances[i]+grid[i][j]])\n",
    "        # 我们需要用一个数组来用BFS遍历所有路径并更新min_distances\n",
    "        \n",
    "        cur_queue = []\n",
    "        cur_queue.append((0,0))\n",
    "        min_distances = [[float(\"inf\") for j in range(len(grid[0]))] for i in range(len(grid))]\n",
    "        min_distances[0][0] = grid[0][0]\n",
    "        cur_queue = set([(0, 1), (1, 0)])\n",
    "        next_queue = set()\n",
    "        while len(cur_queue) > 0:\n",
    "            for row_id, col_id in cur_queue:\n",
    "                if row_id < len(grid) and col_id < len(grid[0]):\n",
    "                    tmp = min_distances[row_id][col_id]\n",
    "                    if row_id - 1 >= 0:\n",
    "                        tmp = min([min_distances[row_id-1][col_id] + grid[row_id][col_id], \n",
    "                                                                        tmp])  \n",
    "                    if col_id - 1 >= 0:\n",
    "                        tmp = min([min_distances[row_id][col_id-1] + grid[row_id][col_id], \n",
    "                                                                        tmp])   \n",
    "                    min_distances[row_id][col_id] = tmp\n",
    "                    next_queue.add((row_id+1, col_id))\n",
    "                    next_queue.add((row_id, col_id+1))\n",
    "            # print(min_distances)\n",
    "            cur_queue = {item for item in next_queue}\n",
    "            next_queue = set()\n",
    "            # break\n",
    "\n",
    "        return min_distances[-1][-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        # 还是有点难度的\n",
    "        def dfs(segId,segStart):\n",
    "            if segId==SEG_COUNT:\n",
    "                if segStart==len(s):\n",
    "                    ipAddre=\".\".join(str(seg) for seg in segments)\n",
    "                    ans.append(ipAddre)\n",
    "                return\n",
    "            if segStart==len(s):\n",
    "                return\n",
    "            if s[segStart]==\"0\":\n",
    "                segments[segId]=0\n",
    "                dfs(segId+1,segStart+1)\n",
    "            addr=0\n",
    "            for segEnd in range(segStart,len(s)):\n",
    "                addr=addr*10+(ord(s[segEnd])-ord(\"0\"))\n",
    "                if 0<addr<=0xFF:\n",
    "                    segments[segId]=addr\n",
    "                    dfs(segId+1,segEnd+1)\n",
    "                else:\n",
    "                    break\n",
    "\n",
    "        SEG_COUNT=4\n",
    "        ans=list()\n",
    "        segments=[0]*SEG_COUNT\n",
    "        dfs(0,0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        output = []\n",
    "        addrs = [0] * 4\n",
    "        def dfs(sid, index):\n",
    "            if sid == 4:\n",
    "                if index == len(s):\n",
    "                    output.append('.'.join([str(d) for d in addrs]))\n",
    "                return\n",
    "\n",
    "            if index == len(s):\n",
    "                if sid == 4:\n",
    "                    output.append('.'.join([str(d) for d in addrs]))\n",
    "\n",
    "                return\n",
    "            \n",
    "            if s[index] == '0':\n",
    "                addrs[sid] = 0\n",
    "                dfs(sid+1, index+1)\n",
    "\n",
    "\n",
    "            addr = 0\n",
    "            for i in range(index, len(s)):\n",
    "                addr = addr * 10 + (ord(s[i]) - ord('0'))\n",
    "\n",
    "                if  0 < addr <= 255:\n",
    "                    addrs[sid] = addr\n",
    "                    dfs(sid+1, i+1)\n",
    "                else:\n",
    "                    break\n",
    "            \n",
    "\n",
    "        dfs(0, 0)\n",
    "\n",
    "\n",
    "\n",
    "        return output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        result = []\n",
    "        seg_count = 4\n",
    "        segments =[0] * seg_count\n",
    "\n",
    "        def dfs(seg_id, start_index):\n",
    "            if seg_id == seg_count:\n",
    "                if start_index == len(s):\n",
    "                    result.append(\".\".join(str(seg) for seg in segments))\n",
    "                return\n",
    "            \n",
    "            if start_index == len(s):\n",
    "                return\n",
    "            \n",
    "            if s[start_index] == \"0\":\n",
    "                segments[seg_id] = \"0\"\n",
    "                dfs(seg_id+1, start_index+1)\n",
    "\n",
    "            addr = 0\n",
    "            for end_index in range(start_index, len(s)):\n",
    "                addr = addr*10 + (ord(s[end_index]) - ord('0'))\n",
    "                if 0 < addr <= 0xFF:\n",
    "                    segments[seg_id] = addr\n",
    "                    dfs(seg_id+1, end_index+1) \n",
    "                else:\n",
    "                    break \n",
    "\n",
    "\n",
    "        dfs(0, 0)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        res, n = [], len(s)\n",
    "\n",
    "        def dfs(i, path):\n",
    "            if len(path) == 4:\n",
    "                if i == n:\n",
    "                    ips = '.'.join([str(seg) for seg in path])\n",
    "                    res.append(ips)\n",
    "                return\n",
    "            \n",
    "            if i == n:\n",
    "                return\n",
    "\n",
    "            if s[i] == '0':\n",
    "                dfs(i+1, path + [0])\n",
    "            \n",
    "            for j in range(i, n):\n",
    "                addr = int(s[i:j+1])\n",
    "                if 0<addr<=255:\n",
    "                    dfs(j+1, path+[addr])\n",
    "                else:\n",
    "                    break\n",
    "        dfs(0, [])\n",
    "        return res\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        SEG_COUNT = 4\n",
    "        ans = list()\n",
    "        segments = [0] * SEG_COUNT\n",
    "        \n",
    "        def backtrack(segId: int, segStart: int):\n",
    "            # 如果找到了 4 段 IP 地址并且遍历完了字符串，那么就是一种答案\n",
    "            if segId == SEG_COUNT:\n",
    "                if segStart == len(s):\n",
    "                    ipAddr = \".\".join(str(seg) for seg in segments)\n",
    "                    ans.append(ipAddr)\n",
    "                return\n",
    "            \n",
    "            # 如果还没有找到 4 段 IP 地址就已经遍历完了字符串，那么提前回溯\n",
    "            if segStart == len(s):\n",
    "                return\n",
    "\n",
    "            # 由于不能有前导零，如果当前数字为 0，那么这一段 IP 地址只能为 0\n",
    "            if s[segStart] == \"0\":\n",
    "                segments[segId] = 0\n",
    "                backtrack(segId + 1, segStart + 1)\n",
    "            \n",
    "            # 一般情况，枚举每一种可能性并递归\n",
    "            addr = 0\n",
    "            for segEnd in range(segStart, len(s)):\n",
    "                addr = addr * 10 + (ord(s[segEnd]) - ord(\"0\"))\n",
    "                if 0 < addr <= 0xFF:\n",
    "                    segments[segId] = addr\n",
    "                    backtrack(segId + 1, segEnd + 1)\n",
    "                else:\n",
    "                    break\n",
    "        \n",
    "\n",
    "        backtrack(0, 0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def combine(self, n: int, k: int) -> List[List[int]]:\n",
    "        def dfs(n,arr,k):\n",
    "            if k <= 0 :\n",
    "                return arr\n",
    "            ans = []\n",
    "            for idx in range(len(arr)):\n",
    "                for i in range(arr[idx][-1]+1,n+1):\n",
    "                    ans.append(arr[idx] + [i])\n",
    "            return dfs(n,ans,k-1)\n",
    "        return dfs(n,[[i] for i in range(1,n-k+2)],k-1)\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        def add(s,arr):\n",
    "            ss = \"\"\n",
    "            idx = 0\n",
    "            for num in arr:\n",
    "                ss += (s[idx:num] + \".\")\n",
    "                idx = num\n",
    "            return ss + s[idx:]\n",
    "        def judge(s):\n",
    "            ss = s.split(\".\")\n",
    "            for sss in ss:\n",
    "                if int(sss) > 255 or (sss[0] == \"0\" and len(sss) > 1):\n",
    "                    return False\n",
    "            return True\n",
    "        n = len(s)\n",
    "        if n == 4:\n",
    "            return [f\"{s[0]}.{s[1]}.{s[2]}.{s[3]}\"]\n",
    "        elif n < 4:\n",
    "            return []\n",
    "        elif n == 12:\n",
    "            ss = f\"{s[:3]}.{s[3:6]}.{s[6:9]}.{s[9:12]}\"\n",
    "            if judge(ss):\n",
    "                return [ss]\n",
    "            else:\n",
    "                return []\n",
    "\n",
    "        if len(s) > 12:\n",
    "            return []\n",
    "        ans = []\n",
    "        conbines = self.combine(n-1,3)\n",
    "        for conbine in conbines:\n",
    "            if conbine[1]-conbine[0] > 3 or conbine[2]-conbine[1] > 3 or n-conbine[2] > 3:\n",
    "                continue\n",
    "            ss = add(s,conbine)\n",
    "            if judge(ss):\n",
    "                ans.append(ss)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        SEG_COUNT = 4\n",
    "        ans = list()\n",
    "        segments = [0] * SEG_COUNT\n",
    "        \n",
    "        def dfs(segId: int, segStart: int):\n",
    "            # 如果找到了 4 段 IP 地址并且遍历完了字符串，那么就是一种答案\n",
    "            if segId == SEG_COUNT:\n",
    "                if segStart == len(s):\n",
    "                    ipAddr = \".\".join(str(seg) for seg in segments)\n",
    "                    ans.append(ipAddr)\n",
    "                return\n",
    "            \n",
    "            # 如果还没有找到 4 段 IP 地址就已经遍历完了字符串，那么提前回溯\n",
    "            if segStart == len(s):\n",
    "                return\n",
    "\n",
    "            # 由于不能有前导零，如果当前数字为 0，那么这一段 IP 地址只能为 0\n",
    "            if s[segStart] == \"0\":\n",
    "                segments[segId] = 0\n",
    "                dfs(segId + 1, segStart + 1)\n",
    "            \n",
    "            # 一般情况，枚举每一种可能性并递归\n",
    "            addr = 0\n",
    "            for segEnd in range(segStart, len(s)):\n",
    "                addr = addr * 10 + (ord(s[segEnd]) - ord(\"0\"))\n",
    "                if 0 < addr <= 0xFF:\n",
    "                    segments[segId] = addr\n",
    "                    dfs(segId + 1, segEnd + 1)\n",
    "                else:\n",
    "                    break\n",
    "        dfs(0, 0)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        SEG_COUNT = 4\n",
    "        ans = list()\n",
    "        segments = [0] * SEG_COUNT\n",
    "\n",
    "        def dfs(segId, segStart):\n",
    "            # 如果找到了4段IP地址并且遍历完了字符串\n",
    "            if segId == SEG_COUNT:\n",
    "                if segStart == len(s):\n",
    "                    ipAddr = \".\".join(str(seg) for seg in segments)\n",
    "                    ans.append(ipAddr)\n",
    "                return\n",
    "            \n",
    "            # 如果还没有找到4段IP地址就已经完成了遍历，那么提前回溯\n",
    "            if segStart == len(s):\n",
    "                return \n",
    "            \n",
    "            # 由于不能有前导0，如果当前数字为0，那么这一段IP地址只能为0\n",
    "            if s[segStart] == \"0\":\n",
    "                segments[segId] = 0\n",
    "                dfs(segId + 1, segStart + 1)\n",
    "            \n",
    "            # 一般情况下，枚举每一种可能\n",
    "            addr = 0\n",
    "            for segEnd in range(segStart, len(s)):\n",
    "                addr = 10 * addr + ord(s[segEnd]) - ord('0')\n",
    "                if 0 < addr <= 255:\n",
    "                    segments[segId] = addr\n",
    "                    dfs(segId + 1, segEnd + 1)\n",
    "                else:\n",
    "                    break\n",
    "        dfs(0, 0)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        segCount = 4\n",
    "        segments = [0] * segCount\n",
    "        ans = []\n",
    "        def dfs(segID,segStart):\n",
    "            if segID == segCount:\n",
    "                if segStart == len(s):\n",
    "                    tmp = '.'.join(str(seg) for seg in segments)\n",
    "                    ans.append(tmp)\n",
    "                return\n",
    "            \n",
    "            if segStart == len(s):\n",
    "                return\n",
    "            \n",
    "            if s[segStart] == '0':\n",
    "                segments[segID] = 0\n",
    "                dfs(segID+1,segStart+1)\n",
    "\n",
    "            add = 0\n",
    "            for segEnd in range(segStart,len(s)):\n",
    "                # add = add *10 + ord(s[segEnd]) - ord('0')\n",
    "                add = add*10 + int(s[segEnd])\n",
    "                if 0 < add <= 255:\n",
    "                    segments[segID] = add\n",
    "                    dfs(segID+1,segEnd+1)\n",
    "                else:\n",
    "                    break\n",
    "            \n",
    "        dfs(0,0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        SEG_COUNT = 4\n",
    "        ans = list()\n",
    "        segments = [0] * SEG_COUNT\n",
    "        \n",
    "        def dfs(segId: int, segStart: int):\n",
    "            # 如果找到了 4 段 IP 地址并且遍历完了字符串，那么就是一种答案\n",
    "            if segId == SEG_COUNT:\n",
    "                if segStart == len(s):\n",
    "                    ipAddr = \".\".join(str(seg) for seg in segments)\n",
    "                    ans.append(ipAddr)\n",
    "                return\n",
    "            \n",
    "            # 如果还没有找到 4 段 IP 地址就已经遍历完了字符串，那么提前回溯\n",
    "            if segStart == len(s):\n",
    "                return\n",
    "\n",
    "            # 由于不能有前导零，如果当前数字为 0，那么这一段 IP 地址只能为 0\n",
    "            if s[segStart] == \"0\":\n",
    "                segments[segId] = 0\n",
    "                dfs(segId + 1, segStart + 1)\n",
    "                return\n",
    "            \n",
    "            # 一般情况，枚举每一种可能性并递归\n",
    "            addr = 0\n",
    "            for segEnd in range(segStart, len(s)):\n",
    "                addr = addr * 10 + (ord(s[segEnd]) - ord(\"0\"))\n",
    "                if 0 < addr <= 0xFF:\n",
    "                    segments[segId] = addr\n",
    "                    dfs(segId + 1, segEnd + 1)\n",
    "                else:\n",
    "                    break\n",
    "        \n",
    "\n",
    "        dfs(0, 0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        SEG_COUNT = 4\n",
    "        ans = list()\n",
    "        segments = [0] * SEG_COUNT\n",
    "        \n",
    "        def dfs(segId: int, segStart: int):\n",
    "            # 如果找到了 4 段 IP 地址并且遍历完了字符串，那么就是一种答案\n",
    "            if segId == SEG_COUNT:\n",
    "                if segStart == len(s):\n",
    "                    ipAddr = \".\".join(str(seg) for seg in segments)\n",
    "                    ans.append(ipAddr)\n",
    "                return\n",
    "            \n",
    "            # 如果还没有找到 4 段 IP 地址就已经遍历完了字符串，那么提前回溯\n",
    "            if segStart == len(s):\n",
    "                return\n",
    "\n",
    "            # 由于不能有前导零，如果当前数字为 0，那么这一段 IP 地址只能为 0\n",
    "            if s[segStart] == \"0\":\n",
    "                segments[segId] = 0\n",
    "                dfs(segId + 1, segStart + 1)\n",
    "            \n",
    "            # 一般情况，枚举每一种可能性并递归\n",
    "            addr = 0\n",
    "            for segEnd in range(segStart, len(s)):\n",
    "                addr = addr * 10 + (ord(s[segEnd]) - ord(\"0\"))\n",
    "                if 0 < addr <= 0xFF:\n",
    "                    segments[segId] = addr\n",
    "                    dfs(segId + 1, segEnd + 1)\n",
    "                else:\n",
    "                    break\n",
    "        \n",
    "\n",
    "        dfs(0, 0)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        \n",
    "        def is_valid(s:str)->bool:\n",
    "            n = len(s)\n",
    "            if n >3:\n",
    "                return False\n",
    "            res  = 0\n",
    "            for  i  in range(len(s)):\n",
    "                res = res*10 +int(s[i])\n",
    "            if  res >255:\n",
    "                return False\n",
    "            if n >=2:\n",
    "                return s[0] !='0'\n",
    "            return True \n",
    "        res = []\n",
    "        def trackback(index:int,path:List[str],num:int):\n",
    "            if  index ==len(s) and  num==4:\n",
    "                iaddr = '.'.join(path.copy())\n",
    "                res.append(iaddr)\n",
    "                return  \n",
    "            if  num>4:\n",
    "                return \n",
    "            for  i in range(index,len(s)):\n",
    "                if is_valid(s[index:i+1]):\n",
    "                    path.append(s[index:i+1])\n",
    "                    trackback(i+1,path,num+1)\n",
    "                    path.pop()\n",
    "        trackback(0,[],0)\n",
    "        return res \n",
    "\n",
    "                \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def restoreIpAddresses(self, s: str) -> List[str]:\n",
    "        SEG_COUNT = 4\n",
    "        ans = list()\n",
    "        segments = [0] * SEG_COUNT\n",
    "        \n",
    "        def dfs(segId: int, segStart: int):\n",
    "            # 如果找到了 4 段 IP 地址并且遍历完了字符串，那么就是一种答案\n",
    "            if segId == SEG_COUNT:\n",
    "                if segStart == len(s):\n",
    "                    ipAddr = \".\".join(str(seg) for seg in segments)\n",
    "                    ans.append(ipAddr)\n",
    "                return\n",
    "            \n",
    "            # 如果还没有找到 4 段 IP 地址就已经遍历完了字符串，那么提前回溯\n",
    "            if segStart == len(s):\n",
    "                return\n",
    "\n",
    "            # 由于不能有前导零，如果当前数字为 0，那么这一段 IP 地址只能为 0\n",
    "            if s[segStart] == \"0\":\n",
    "                segments[segId] = 0\n",
    "                dfs(segId + 1, segStart + 1)\n",
    "            \n",
    "            # 一般情况，枚举每一种可能性并递归\n",
    "            addr = 0\n",
    "            for segEnd in range(segStart, len(s)):\n",
    "                addr = addr * 10 + (ord(s[segEnd]) - ord(\"0\"))\n",
    "                if 0 < addr <= 0xFF:\n",
    "                    segments[segId] = addr\n",
    "                    dfs(segId + 1, segEnd + 1)\n",
    "                else:\n",
    "                    break\n",
    "        \n",
    "\n",
    "        dfs(0, 0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import *\n",
    "class Solution:\n",
    "    def largestRectangleArea(self, heights: List[int]) -> int:\n",
    "        ans = 0\n",
    "        g = defaultdict(list)\n",
    "        n = len(heights)\n",
    "        sl = SortedList()\n",
    "        for i, x in enumerate(heights): g[x].append(i)\n",
    "        for x in sorted(set(heights)):\n",
    "            for i in g[x]:\n",
    "                p = sl.bisect_left(i)-1\n",
    "                l = sl[p] if 0 <= p < len(sl) else -1\n",
    "                p = sl.bisect_left(i)\n",
    "                r = sl[p] if 0 <= p < len(sl) else n\n",
    "                ans = max(ans, (r-l - 1) * x)\n",
    "            for i in g[x]: sl.add(i)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import sortedcontainers\n",
    "class Solution:\n",
    "    def largestRectangleArea(self, heights: List[int]) -> int:\n",
    "        l = sorted((h, p) for p, h in enumerate(heights))\n",
    "        place = sortedcontainers.SortedList([-1, len(heights)])\n",
    "        res = 0\n",
    "        for h, p in l:\n",
    "            p1 = place.bisect(p)\n",
    "            res = max(res, h*(place[p1]-place[p1-1]-1) )\n",
    "            place.add(p)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        \n",
    "        k=len(expeditions)\n",
    "        \n",
    "        t=expeditions[0].split('->')\n",
    "        a=set(t) \n",
    "        ans=index=-1\n",
    "        \n",
    "        a.add('')\n",
    "        big=0\n",
    "        for i in range(1,k):\n",
    "            w=expeditions[i].split('->')\n",
    "            w=set(w)\n",
    "            t=len(w-a)\n",
    "            if t>big:\n",
    "                big=t\n",
    "                ans=i\n",
    "            a|=w\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        s = set(expeditions[0].split('->'))\n",
    "        n = len(expeditions)\n",
    "        ans = -1\n",
    "        pre = 0\n",
    "        for i in range(1, n):\n",
    "            ts = set()\n",
    "            for ex in expeditions[i].split('->'):\n",
    "                if ex not in s and len(ex): ts.add(ex)\n",
    "            print(ts, len(ts), len(ts) > pre)\n",
    "            s |= ts\n",
    "            if len(ts) > pre:\n",
    "                ans = i\n",
    "                pre = len(ts)\n",
    "        return ans\n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, ee: List[str]) -> int:\n",
    "        k=len(ee)\n",
    "        t=ee[0].split('->')\n",
    "        a=set(t) \n",
    "        ans=index=-1\n",
    "        a.add('')\n",
    "        big=0\n",
    "        for i in range(1,k):\n",
    "            w= set(ee[i].split('->'))\n",
    "            if (t:=len(w-a))>big:\n",
    "                big=t\n",
    "                ans=i\n",
    "            a|=w\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, ee: List[str]) -> int:\n",
    "        \n",
    "        k=len(ee)\n",
    "        \n",
    "        t=ee[0].split('->')\n",
    "        a=set(t) \n",
    "        ans=index=-1\n",
    "        \n",
    "        a.add('')\n",
    "        big=0\n",
    "        for i in range(1,k):\n",
    "            w= set(ee[i].split('->'))\n",
    "          \n",
    "            \n",
    "            if (t:=len(w-a))>big:\n",
    "                big=t\n",
    "                ans=i\n",
    "            a|=w\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        max_index = 0\n",
    "        max_counter = 0\n",
    "        exp = set(expeditions[0].split(\"->\"))\n",
    "        for i, e in enumerate(expeditions[1:]):\n",
    "            if e == \"\":\n",
    "                continue\n",
    "            c = 0\n",
    "            for name in e.split(\"->\"):\n",
    "                if name not in exp:\n",
    "                    exp.add(name)\n",
    "                    c += 1\n",
    "            if c > max_counter:\n",
    "                max_counter = c\n",
    "                max_index = i\n",
    "        return max_index + 1 if max_counter > 0 else -1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        a = expeditions\n",
    "        ans = 0\n",
    "        ansI = -1\n",
    "        data = set(a[0].split(\"->\"))\n",
    "        if \"\" in data:\n",
    "                data.remove(\"\")\n",
    "        for i in range(1, len(a)):\n",
    "            d = set(a[i].split(\"->\"))\n",
    "            if \"\" in d:\n",
    "                d.remove(\"\")\n",
    "            c = 0\n",
    "            for j in d:\n",
    "                if j not in data:\n",
    "                    c += 1\n",
    "                    data.add(j)\n",
    "            if c > ans:\n",
    "                ans = c\n",
    "                ansI = i\n",
    "        return ansI\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        s = set()\n",
    "        for c in self.string_to_list(expeditions[0]):\n",
    "            s.add(c)\n",
    "        res = -1\n",
    "        max_find = 0\n",
    "        for i in range(1, len(expeditions)):\n",
    "            print(f'i: {i}')\n",
    "            if len(expeditions[i]) == 0:\n",
    "                continue\n",
    "            cur = 0\n",
    "            for c in self.string_to_list(expeditions[i]):\n",
    "                if c not in s:\n",
    "                    cur += 1\n",
    "                    s.add(c)\n",
    "            if cur > max_find:\n",
    "                max_find = cur\n",
    "                res = i\n",
    "            print(f'cur: {cur}')\n",
    "        return res\n",
    "\n",
    "    def string_to_list(self, e):\n",
    "        return e.split('->')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        s = set()\n",
    "        for c in self.string_to_list(expeditions[0]):\n",
    "            s.add(c)\n",
    "        res = -1\n",
    "        max_find = 0\n",
    "        for i in range(1, len(expeditions)):\n",
    "            # print(f'i: {i}')\n",
    "            if len(expeditions[i]) == 0:\n",
    "                continue\n",
    "            cur = 0\n",
    "            for c in self.string_to_list(expeditions[i]):\n",
    "                if c not in s:\n",
    "                    cur += 1\n",
    "                    s.add(c)\n",
    "            if cur > max_find:\n",
    "                max_find = cur\n",
    "                res = i\n",
    "            # print(f'cur: {cur}')\n",
    "        return res\n",
    "\n",
    "    def string_to_list(self, e):\n",
    "        return e.split('->')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        seen = set()\n",
    "        res = max_val = 0\n",
    "        for i, e in enumerate(expeditions):\n",
    "            if not e:\n",
    "                continue\n",
    "            camps = list(e.split('->'))\n",
    "            count = 0 \n",
    "            \n",
    "            for c in camps:\n",
    "                if c not in seen:\n",
    "                    count += 1\n",
    "                    seen.add(c)\n",
    "            # print(camps, count)\n",
    "            if i > 0 and count > max_val:\n",
    "                max_val = count\n",
    "                res = i \n",
    "        return res if res else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        find = set(expeditions[0].split(\"->\"))\n",
    "        nums=0\n",
    "        res=-1\n",
    "        for i in range(1,len(expeditions)):\n",
    "            count = 0\n",
    "            if expeditions[i]==\"\":\n",
    "                continue\n",
    "            for item in expeditions[i].split(\"->\"):\n",
    "                if item not in find:\n",
    "                    count+=1\n",
    "                    find.add(item)\n",
    "            if count>nums:\n",
    "                nums=count\n",
    "                res=i\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        ans = 0\n",
    "        result = -1\n",
    "        n = len(expeditions)\n",
    "        cnt0 = set(expeditions[0].split(\"->\"))\n",
    "        for i in range(1,n):\n",
    "            if expeditions[i]==\"\":\n",
    "                continue\n",
    "            c = 0\n",
    "            cnt1 = set(expeditions[i].split(\"->\"))\n",
    "            \n",
    "            for temp in cnt1:\n",
    "                if temp not in cnt0:\n",
    "                    cnt0.add(temp)\n",
    "                    c+=1\n",
    "            if c>ans:\n",
    "                ans = c\n",
    "                result = i\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        already_know = set(expeditions[0].split('->'))\n",
    "        max_num, ans = 0, -1\n",
    "        for i in range(1, len(expeditions)):\n",
    "            cnt = 0\n",
    "            if expeditions[i] == '':\n",
    "                continue\n",
    "            for camp in expeditions[i].split('->'):\n",
    "                if camp not in already_know:\n",
    "                    already_know.add(camp)\n",
    "                    cnt += 1\n",
    "            if cnt > max_num:\n",
    "                max_num, ans = cnt, i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        visited = set(expeditions[0].split(\"->\")) if len(expeditions[0]) > 0 else set()\n",
    "        max_new, max_index = 0, -1\n",
    "        for i in range(1, len(expeditions)):\n",
    "            camps = expeditions[i].split(\"->\")\n",
    "            num_new = 0\n",
    "            for camp in camps:\n",
    "                if len(camp) > 0 and camp not in visited:\n",
    "                    visited.add(camp)\n",
    "                    num_new += 1\n",
    "            if num_new > max_new:\n",
    "                max_new = num_new\n",
    "                max_index = i\n",
    "        return max_index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        start=expeditions[0].split(\"->\")\n",
    "        sstart=set(start)\n",
    "        res=0\n",
    "        ans=-1\n",
    "        for i in range(1,len(expeditions)):\n",
    "            temp=expeditions[i].split(\"->\")\n",
    "            cnt=0\n",
    "            for ss in temp:\n",
    "                if ss not in sstart and ss!=\"\":\n",
    "                    sstart.add(ss)\n",
    "                    cnt+=1\n",
    "            if cnt>res:\n",
    "                res=cnt\n",
    "                ans=i\n",
    "        return ans\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        res = -1\n",
    "        t = 0\n",
    "        n = len(expeditions)\n",
    "        e = set(expeditions[0].split('->'))\n",
    "        for i in range(1, n):\n",
    "            cnt = 0\n",
    "            temp = expeditions[i].split('->')\n",
    "            for ex in temp:\n",
    "                if ex and ex not in e:\n",
    "                    cnt += 1\n",
    "                    e.add(ex)\n",
    "            if cnt > t:\n",
    "                res = i\n",
    "                t = cnt\n",
    "        return res\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        # seen = set()\n",
    "        # res = max_val = 0\n",
    "        # for i, e in enumerate(expeditions):\n",
    "        #     if not e:\n",
    "        #         continue\n",
    "        #     camps = list(e.split('->'))\n",
    "        #     count = 0             \n",
    "        #     for c in camps:\n",
    "        #         if c not in seen:\n",
    "        #             count += 1\n",
    "        #             seen.add(c)\n",
    "        #     if i > 0 and count > max_val:\n",
    "        #         max_val = count\n",
    "        #         res = i \n",
    "        # return res if res else -1\n",
    "\n",
    "        # -------------------------------\n",
    "        seen = set(expeditions[0].split('->'))\n",
    "        res, max_val = -1, 0\n",
    "        for i in range(1, len(expeditions)):\n",
    "            if not expeditions[i]:\n",
    "                continue\n",
    "            count = 0\n",
    "            for e in expeditions[i].split('->'):\n",
    "                if e not in seen:\n",
    "                    seen.add(e)\n",
    "                    count += 1\n",
    "            if count > max_val:\n",
    "                max_val = count\n",
    "                res = i \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, a: List[str]) -> int:\n",
    "        vis = set(a[0].split('->'))  # 这样可能会把空串插入，但是没有关系\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(a)):\n",
    "            if a[i] == \"\": continue\n",
    "            cnt = 0\n",
    "            for t in a[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        vis = set(expeditions[0].split('->'))\n",
    "        max_cnt, ans = 0, -1\n",
    "        for i in range(1, len(expeditions)):\n",
    "            if expeditions[i] == '': continue\n",
    "            cnt = 0\n",
    "            for t in expeditions[i].split('->'):\n",
    "                if t not in vis:\n",
    "                    vis.add(t)\n",
    "                    cnt += 1\n",
    "            if cnt > max_cnt:\n",
    "                max_cnt, ans = cnt, i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def adventureCamp(self, expeditions: List[str]) -> int:\n",
    "        start = set(expeditions[0].split(\"->\"))\n",
    "        if expeditions[0].find(\"->\") < 0:\n",
    "            start.clear()\n",
    "            if expeditions[0] != \"\": start.add(expeditions[0])\n",
    "        idx, num = -1, 0\n",
    "        for i in range(1, len(expeditions)):\n",
    "            cur = set(expeditions[i].split(\"->\"))\n",
    "            if expeditions[i].find(\"->\") < 0:\n",
    "                cur.clear()\n",
    "                if expeditions[i] != \"\": cur.add(expeditions[i])\n",
    "            for ch in start:\n",
    "                if ch in cur: cur.remove(ch)\n",
    "            for ch in cur: start.add(ch)\n",
    "            if len(cur) > num:\n",
    "                num = len(cur)\n",
    "                idx = i\n",
    "        return idx\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans=set()\n",
    "        length =len(nums)\n",
    "        if(length<3):return []\n",
    "        for i in range(length-2):\n",
    "            target=-nums[i]\n",
    "            j=i+1\n",
    "            k=length-1\n",
    "            while(j<k):\n",
    "                total=nums[j]+nums[k]\n",
    "                if(total<target):\n",
    "                    j+=1\n",
    "                elif(total>target):\n",
    "                    k-=1\n",
    "                else:\n",
    "                    ans.add((nums[i],nums[j],nums[k]))\n",
    "                    j+=1\n",
    "                    # break\n",
    "        # [0,0,0,0] 重复错误,下进行重复检查 set去重\n",
    "        # print(ans)\n",
    "        answer=list(ans)\n",
    "        # print(answer)\n",
    "        return answer\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        group = set()\n",
    "        for i in range(len(nums)-2):\n",
    "            j,k = i+1, len(nums) -1\n",
    "            while j < k:\n",
    "                if nums[i] + nums[j] + nums[k] == 0:\n",
    "                    group.add((nums[i], nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                elif  nums[i] + nums[j] + nums[k] > 0:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1 \n",
    "        return list(group)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        if not nums or len(nums) < 3:\n",
    "            return []\n",
    "        ans = set([])\n",
    "        for i in range(len(nums)):\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1 \n",
    "            while l < r:\n",
    "                if nums[l] + nums[r] + nums[i] < 0:\n",
    "                    l+=1\n",
    "                elif nums[l] + nums[r] + nums[i] > 0:\n",
    "                    r-=1\n",
    "                else: \n",
    "                    ans.add((nums[l] , nums[r] , nums[i]))\n",
    "                    l+=1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums)<3:\n",
    "            return []\n",
    "        nums.sort()#\n",
    "        target=0\n",
    "        ans =set()\n",
    "        for i in range(len(nums)-2):\n",
    "                now = nums[i]\n",
    "                p=i+1\n",
    "                q=len(nums)-1\n",
    "                while p<q:\n",
    "                    if now+nums[p]+nums[q]==target:\n",
    "                        if (nums[i],nums[p],nums[q]) not in ans:\n",
    "                            ans.add((nums[i],nums[p],nums[q]))\n",
    "                    if now+nums[p]+nums[q] > target:\n",
    "                        q-=1\n",
    "                    else:\n",
    "                        p+=1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        res = set()\n",
    "        for i in range(len(nums)):\n",
    "            l = i-1\n",
    "            r = i+1\n",
    "            while l >= 0 and r < len(nums):\n",
    "                s = nums[l] + nums[i] + nums[r]\n",
    "                tmpl = nums[l]\n",
    "                tmpr = nums[r]\n",
    "                if s == 0:\n",
    "\n",
    "                    res.add((nums[l], nums[i], nums[r]))\n",
    "                    r += 1\n",
    "                    l -= 1\n",
    "                elif s < 0:\n",
    "                    r += 1\n",
    "                else:\n",
    "                    l -= 1\n",
    "        return list(res)\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        if not nums or len(nums) < 3:\n",
    "            return []\n",
    "        ans = set([])\n",
    "        for i in range(len(nums)):\n",
    "            l = i + 1\n",
    "            r = len(nums) - 1 \n",
    "            while l < r:\n",
    "                if nums[l] + nums[r] + nums[i] < 0:\n",
    "                    l+=1\n",
    "                elif nums[l] + nums[r] + nums[i] > 0:\n",
    "                    r-=1\n",
    "                else: \n",
    "                    ans.add((nums[l] , nums[r] , nums[i]))\n",
    "                    l+=1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums = sorted(nums)\n",
    "        ans = set()\n",
    "        for i in range(len(nums)-2):\n",
    "            l, r = i+1, len(nums)-1\n",
    "            while l < r:\n",
    "                if nums[i]+nums[l]+nums[r] == 0:\n",
    "                    ans.add((nums[i], nums[l], nums[r]))\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                elif nums[i]+nums[l]+nums[r] < 0:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1\n",
    "        return list(ans)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = set()\n",
    "        n = len(nums)\n",
    "        if n < 3:\n",
    "            return []\n",
    "        \n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            left, right = i + 1, n - 1\n",
    "            while left < right:\n",
    "                if nums[i] + nums[left] + nums[right] == 0:\n",
    "                    res.add((nums[i], nums[left], nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif nums[i] + nums[left] + nums[right] < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return list(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        def process(nums,tar):\n",
    "            i,j = 0,len(nums) - 1\n",
    "            result = []\n",
    "            hashmap = set()\n",
    "            while i < j:\n",
    "                if nums[i] in hashmap:\n",
    "                    i += 1\n",
    "                    continue\n",
    "                if nums[j] in hashmap:\n",
    "                    j -= 1\n",
    "                    continue\n",
    "\n",
    "                cur = nums[i] + nums[j]\n",
    "                if cur > tar:\n",
    "                    j -= 1\n",
    "                elif cur < tar:\n",
    "                    i += 1\n",
    "                else:\n",
    "                    if nums[i] not in hashmap or nums[j] not in hashmap:\n",
    "                        result.append([nums[i],nums[j],-1*tar])\n",
    "                        hashmap.add(nums[i])\n",
    "                        hashmap.add(nums[j])\n",
    "                    i += 1\n",
    "                    j -= 1\n",
    "            return result\n",
    "        \n",
    "        nums.sort()\n",
    "        result = []\n",
    "        last = None\n",
    "        while len(nums) > 2:\n",
    "\n",
    "            tar = nums.pop() \n",
    "            if last == tar:\n",
    "                continue\n",
    "            last = tar\n",
    "            tp = process(nums,-1*tar)\n",
    "            if tp:\n",
    "                result.extend(tp)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        if n < 3:return []\n",
    "        dic = Counter(nums)\n",
    "        ans = set()\n",
    "        nums.sort()\n",
    "        for i in range(n-2):\n",
    "            for j in range(i+1,n-1):\n",
    "                t = 0 - nums[i] - nums[j]\n",
    "                if t<nums[j]:\n",
    "                    break\n",
    "                elif t in dic:\n",
    "                    if t == 0:\n",
    "                        if dic[0]>2:\n",
    "                            ans.add((0,0,0))\n",
    "                    elif t == nums[j]:\n",
    "                        if dic[t]>1:\n",
    "                            ans.add((nums[i],nums[j],t))\n",
    "                    else:\n",
    "                        ans.add((nums[i],nums[j],t))\n",
    "        return [list(i) for i in ans]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        def process(nums,tar):\n",
    "            i,j = 0,len(nums) - 1\n",
    "            result = []\n",
    "            hashmap = set()\n",
    "            while i < j:\n",
    "                if nums[i] in hashmap:\n",
    "                    i += 1\n",
    "                    continue\n",
    "                if nums[j] in hashmap:\n",
    "                    j -= 1\n",
    "                    continue\n",
    "\n",
    "                cur = nums[i] + nums[j]\n",
    "                if cur > tar:\n",
    "                    j -= 1\n",
    "                elif cur < tar:\n",
    "                    i += 1\n",
    "                else:\n",
    "                    if nums[i] not in hashmap or nums[j] not in hashmap:\n",
    "                        result.append([nums[i],nums[j],-1*tar])\n",
    "                        hashmap.add(nums[i])\n",
    "                        hashmap.add(nums[j])\n",
    "                    i += 1\n",
    "                    j -= 1\n",
    "            return result\n",
    "        \n",
    "        nums.sort()\n",
    "        result = []\n",
    "        hashmap = set()\n",
    "        while len(nums) > 2:\n",
    "            tar = nums.pop()\n",
    "            if tar in hashmap:\n",
    "                continue\n",
    "            hashmap.add(tar)\n",
    "            tp = process(nums,-1*tar)\n",
    "            if tp:\n",
    "                result.extend(tp)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        str_set = set()\n",
    "        ans = []\n",
    "        for i in range(len(nums)-2):\n",
    "            num = nums[i]\n",
    "            num_dict = {}\n",
    "            for j in range(i+1, len(nums)):\n",
    "                if -(nums[j] + nums[i]) in num_dict:\n",
    "                    seq = [nums[j], nums[i], -(nums[i]+nums[j])]\n",
    "                    seq.sort()\n",
    "                    if str(seq) not in str_set:\n",
    "                        ans.append(seq)\n",
    "                        str_set.add(str(seq))\n",
    "                num_dict[nums[j]] = j\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans=set()\n",
    "        for i in range(len(nums)-2):\n",
    "            if nums[i]>0:break\n",
    "            for j in range(i+1,len(nums)-1):\n",
    "                num = nums[i]+nums[j]\n",
    "                m=j+1\n",
    "                n=len(nums)\n",
    "                while m<n:\n",
    "                    mid = ((n-m)>>1)+m\n",
    "                    if -num == nums[mid]:\n",
    "                        ans.add((nums[i],nums[j],nums[mid]))\n",
    "                        break\n",
    "                    if -num > nums[mid]:\n",
    "                        m=mid+1\n",
    "                    else:\n",
    "                        n=mid\n",
    "        return [list(i) for i in ans]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)       \n",
    "        nums.sort()\n",
    "        # res = []\n",
    "        ans = set()\n",
    "        for i in range(n-2):\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                sum = nums[i] + nums[left] + nums[right]\n",
    "                    # res.append([nums[i],nums[left],nums[right]])\n",
    "                if sum < 0:\n",
    "                    left += 1\n",
    "                elif sum > 0:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    ans.add((nums[i],nums[left],nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1                    \n",
    "        return [list(a) for a in ans]\n",
    "                \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums=sorted(nums)\n",
    "        n=len(nums)\n",
    "        res=set()\n",
    "        for i in range(n-2):\n",
    "            k=n-1\n",
    "            for j in range(i+1,n-1):\n",
    "                while nums[i]+nums[j]+nums[k]>=0 and j<k:\n",
    "                    if nums[i]+nums[j]+nums[k]==0:\n",
    "                        res.add((nums[i],nums[j],nums[k]))\n",
    "                    k-=1\n",
    "                if j>=k:\n",
    "                    break\n",
    "        return [list(result) for result in res]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "        n = len(nums)\n",
    "        for i in range(n - 2):\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            x = nums[i]\n",
    "            while j < k:\n",
    "                cur = x + nums[j] + nums[k]\n",
    "                if cur > 0:\n",
    "                    k -= 1\n",
    "                elif cur < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    ans.add((x, nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "        return [list(a) for a in ans]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        #1e3 1e6<1e8\n",
    "\n",
    "        result=[]\n",
    "        r=set()\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            end=len(nums)-1\n",
    "            start=i+1\n",
    "            while start<end:\n",
    "                if nums[start]+nums[end]+nums[i]>0:\n",
    "                    end-=1\n",
    "                elif nums[start]+nums[end]+nums[i]<0:\n",
    "                    start+=1\n",
    "                elif nums[start]+nums[end]+nums[i]==0:\n",
    "                    if (nums[i],nums[start],nums[end]) not in r:\n",
    "                        result.append([nums[i],nums[start],nums[end]])\n",
    "                        r.add((nums[i],nums[start],nums[end]))\n",
    "                    start+=1\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        nums.sort()\n",
    "        n = len(nums)\n",
    "        start = 0\n",
    "        res_set = set()\n",
    "        for start in range(n - 2):\n",
    "            left = start + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                cur_sum = nums[start] + nums[left] + nums[right]\n",
    "                if cur_sum == 0:\n",
    "                    res_set.add((nums[start], nums[left], nums[right]))\n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif cur_sum > 0:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "        res = [list(x) for x in res_set]\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        rs = set()\n",
    "        n = len(nums)\n",
    "        for idx,val in enumerate(nums):\n",
    "            if val == 0 and idx+2 < n and nums[idx+2] == 0:\n",
    "                rs.add((0,0,0))\n",
    "                continue\n",
    "            \n",
    "            target = -val\n",
    "            l,r = idx+1,n-1\n",
    "            while l < r:\n",
    "                s = nums[l]+nums[r]\n",
    "                if s == target:\n",
    "                    rs.add((val,nums[l],nums[r]))\n",
    "                    l += 1\n",
    "                elif s < target:\n",
    "                    l += 1\n",
    "                else:\n",
    "                    r -= 1 \n",
    "        return [[a,b,c] for (a,b,c) in rs]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "        \n",
    "        nums.sort()\n",
    "        ans = []\n",
    "        firstnum_set = set()\n",
    "        ans_set = set()\n",
    "        for i in range(len(nums) - 2):\n",
    "            base = nums[i]\n",
    "            firstnum_set.add(base)\n",
    "            left = i + 1\n",
    "            right = len(nums) - 1\n",
    "            target = 0 - base\n",
    "\n",
    "            while left < right:\n",
    "                if nums[left] + nums[right] == target:\n",
    "                    if (base,nums[left],nums[right]) not in ans_set:\n",
    "                        ans.append([base,nums[left],nums[right]])\n",
    "                        ans_set.add((base,nums[left],nums[right]))\n",
    "                \n",
    "                    left += 1\n",
    "                    right -= 1\n",
    "                elif nums[left] + nums[right] < target:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "\n",
    "        for i in range(n):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            while j < k:\n",
    "                tmp = nums[i] + nums[j] + nums[k]\n",
    "                if tmp == 0:\n",
    "                    ans.add((nums[i], nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                elif tmp < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    k -= 1\n",
    "\n",
    "        # ans = list(ans)\n",
    "\n",
    "        return [list(a) for a in ans]\n",
    "\n",
    "\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "        n = len(nums)\n",
    "        for i in range(n - 2):\n",
    "            j = i + 1\n",
    "            k = n - 1\n",
    "            x = nums[i]\n",
    "            while j < k:\n",
    "                cur = x + nums[j] + nums[k]\n",
    "                if cur > 0:\n",
    "                    k -= 1\n",
    "                elif cur < 0:\n",
    "                    j += 1\n",
    "                else:\n",
    "                    ans.add((x, nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "        return [list(a) for a in ans]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        # 如果是已经排序好的话，则时间复杂度位 O(n^2)\n",
    "        def twosum(nums, start, target):\n",
    "            left, right = start, len(nums) - 1\n",
    "            lr_list = []\n",
    "            while left < right:\n",
    "                sumval = nums[left] + nums[right]\n",
    "                if sumval == target:\n",
    "                    lr_list.append([left, right])\n",
    "                    right -= 1\n",
    "                elif sumval > target:\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    left += 1\n",
    "            return lr_list\n",
    "        nums.sort()\n",
    "        flagSet = set()\n",
    "        result = []\n",
    "        N = len(nums)\n",
    "        for i in range(N-2):\n",
    "            target = 0 - nums[i]\n",
    "            lr_list = twosum(nums, i+1, target)\n",
    "            if len(lr_list) != 0:\n",
    "                for lr in lr_list:\n",
    "                    lstr = str([nums[i], nums[lr[0]], nums[lr[1]]])\n",
    "                    if lstr not in flagSet:\n",
    "                        result.append([nums[i], nums[lr[0]], nums[lr[1]]])\n",
    "                        flagSet.add(lstr)\n",
    "        return result\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = set()\n",
    "        nums.sort()\n",
    "        for index, num in enumerate(nums):\n",
    "            start, end = index + 1, len(nums) - 1\n",
    "            target = -num\n",
    "            while start < end:\n",
    "                if nums[start] + nums[end] == target:\n",
    "                    result.add(tuple(sorted([nums[start], nums[end], num])))\n",
    "                    start += 1\n",
    "                    end -= 1\n",
    "                elif nums[start] + nums[end] < target:\n",
    "                    start += 1\n",
    "                else:\n",
    "                    end -= 1\n",
    "        result = [list(res) for res in result]\n",
    "        return list(result)\n",
    "\n",
    "\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSteps(self, n: int) -> int:\n",
    "        s=set()\n",
    "        unv=[['A',0,'']]\n",
    "        while(True):\n",
    "            v,cnt,p=unv.pop(0)\n",
    "            if len(v)==n:return cnt\n",
    "            if (v,p) not in s and len(v)<n:\n",
    "                s.add((v,p))\n",
    "                unv.append([v,cnt+1,v])\n",
    "                unv.append([v+p,cnt+1,p])\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSteps(self, n: int) -> int:\n",
    "        vis = set()\n",
    "        def process(have, copy):\n",
    "            if have == n:\n",
    "                return 0\n",
    "\n",
    "            if have > n:\n",
    "                return float(\"inf\")\n",
    "\n",
    "            if (have, copy) in vis:\n",
    "                return float(\"inf\")\n",
    "\n",
    "            vis.add((have, copy))\n",
    "\n",
    "            # 复制全部\n",
    "            res = 1 + process(have, have)\n",
    "            # 粘贴\n",
    "            if copy:\n",
    "                res = min(res, 1 + process(have+copy, copy))\n",
    "            return res\n",
    "\n",
    "        if n == 1:\n",
    "            return 0\n",
    "        return process(1, 1) + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def judgePoint24(self, cards: List[int]) -> bool:\n",
    "        # 列表选两个数，计算之后放回新列表，然后继续dfs, 直到只剩一个数，然后判断\n",
    "        def dfs(nums):\n",
    "            target, eps=24, 1e-6\n",
    "            add, subs, mul, did=0, 1, 2, 3\n",
    "            if not nums:\n",
    "                return False\n",
    "            if len(nums)==1:\n",
    "                return abs(nums[0]-target)<eps\n",
    "            for i, x in enumerate(nums):\n",
    "                for j, y in enumerate(nums):\n",
    "                    if i!=j:\n",
    "                        new_nums=[]\n",
    "                        for k, z in enumerate(nums):\n",
    "                            if k!=i and k!=j:\n",
    "                                new_nums.append(z)\n",
    "                        for op in range(4):\n",
    "                            if op in [0, 2] and i>j:# + *满足交换律\n",
    "                                continue\n",
    "                            if op==0:\n",
    "                                new_nums.append(x+y)\n",
    "                            if op==1:\n",
    "                                new_nums.append(x-y)\n",
    "                            if op==2:\n",
    "                                new_nums.append(x*y)\n",
    "                            if op==3:\n",
    "                                if y<eps:\n",
    "                                    continue\n",
    "                                new_nums.append(x/y)\n",
    "                            if dfs(new_nums):\n",
    "                                return True\n",
    "                            new_nums.pop()\n",
    "            return False\n",
    "        return dfs(cards)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def judgePoint24(self, cards: List[int]) -> bool:\n",
    "            # 判断是否能够通过运算得到24\n",
    "        def search(numbers):\n",
    "            # 如果只剩一个数，检查它是否接近24\n",
    "            if len(numbers) == 1:\n",
    "                return abs(numbers[0] - 24) < 1e-6\n",
    "\n",
    "            # 尝试所有的配对\n",
    "            for i in range(len(numbers)):\n",
    "                for j in range(len(numbers)):\n",
    "                    if i != j:\n",
    "                        # 对于每一对配对，尝试每种运算\n",
    "                        for op in [add, sub, mul, truediv]:\n",
    "                            if (op in [add, mul] and i >= j):\n",
    "                                continue\n",
    "                            # 除法运算需要注意除数不为零\n",
    "                            if op is truediv and numbers[j] == 0:\n",
    "                                continue\n",
    "                            next_numbers = [numbers[k] for k in range(len(numbers)) if k != i and k != j]\n",
    "                            next_numbers.append(op(numbers[i], numbers[j]))\n",
    "                            if search(next_numbers):\n",
    "                                return True\n",
    "            return False\n",
    "\n",
    "        # 尝试所有数字的排列组合\n",
    "        for perm in permutations(cards):\n",
    "            if search(list(perm)):\n",
    "                return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from operator import truediv, mul, add, sub\n",
    "\n",
    "class Solution(object):\n",
    "    def judgePoint24(self, A):\n",
    "        if not A: return False\n",
    "        if len(A) == 1: return abs(A[0] - 24) < 1e-6\n",
    "\n",
    "        for i in range(len(A)):\n",
    "            for j in range(len(A)):\n",
    "                if i != j:\n",
    "                    B = [A[k] for k in range(len(A)) if i != k != j]\n",
    "                    for op in (truediv, mul, add, sub):\n",
    "                        if (op is add or op is mul) and j > i: continue\n",
    "                        if op is not truediv or A[j]:\n",
    "                            B.append(op(A[i], A[j]))\n",
    "                            if self.judgePoint24(B): return True\n",
    "                            B.pop()\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def judgePoint24(self, cards: List[int]) -> bool:\n",
    "            # 判断是否能够通过运算得到24\n",
    "        def search(numbers):\n",
    "            # 如果只剩一个数，检查它是否接近24\n",
    "            if len(numbers) == 1:\n",
    "                return abs(numbers[0] - 24) < 1e-6\n",
    "\n",
    "            # 尝试所有的配对\n",
    "            for i in range(len(numbers)):\n",
    "                for j in range(len(numbers)):\n",
    "                    if i != j:\n",
    "                        # 对于每一对配对，尝试每种运算\n",
    "                        for op in [add, sub, mul, truediv]:\n",
    "                            if (op in [add, mul] and i >= j):\n",
    "                                continue\n",
    "                            # 除法运算需要注意除数不为零\n",
    "                            if op is truediv and numbers[j] == 0:\n",
    "                                continue\n",
    "                            next_numbers = [numbers[k] for k in range(len(numbers)) if k != i and k != j]\n",
    "                            next_numbers.append(op(numbers[i], numbers[j]))\n",
    "                            if search(next_numbers):\n",
    "                                return True\n",
    "            return False\n",
    "\n",
    "        # 尝试所有数字的排列组合\n",
    "        # for perm in permutations(cards):\n",
    "        #     if search(list(perm)):\n",
    "        #         return True\n",
    "        return search(cards)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def judgePoint24(self, cards: List[int]) -> bool:\n",
    "        def lt679(cards):\n",
    "            def add(n1,n2):\n",
    "                nome1,de1,nome2,de2=n1[0],n1[1],n2[0],n2[1]\n",
    "                lcm=math.lcm(de1,de2)\n",
    "                nome1*=(lcm//de1)\n",
    "                nome2*=(lcm//de2)\n",
    "                return [nome1+nome2,lcm]\n",
    "            def sub(n1,n2):\n",
    "                nome1, de1, nome2, de2 = n1[0], n1[1], n2[0], n2[1]\n",
    "                lcm = math.lcm(de1, de2)\n",
    "                nome1 *= (lcm // de1)\n",
    "                nome2 *= (lcm // de2)\n",
    "                return [nome1 - nome2, lcm]\n",
    "            def mul(n1,n2):\n",
    "                nome1, de1, nome2, de2 = n1[0], n1[1], n2[0], n2[1]\n",
    "                nome=nome1*nome2\n",
    "                de=de1*de2\n",
    "                gcd=math.gcd(nome,de)\n",
    "                nome//=gcd\n",
    "                de//=gcd\n",
    "                return [nome,de]\n",
    "            def dev(n1,n2):\n",
    "                return mul(n1,[n2[1],n2[0]])\n",
    "            def is_zero(n):\n",
    "                return n[0]==0\n",
    "            def is_24(n):\n",
    "                return n[0]%n[1]==0 and n[0]//n[1]==24\n",
    "            def dfs(nums):\n",
    "                n=len(nums)\n",
    "                if n==1:return is_24(nums[0])\n",
    "                res=[]\n",
    "                for i in range(n-1):\n",
    "                    n1,n2=nums[i],nums[i+1]\n",
    "                    pre,succ=nums[:i],nums[i+2:]\n",
    "                    res.append(dfs(pre+[add(n1,n2)]+succ))\n",
    "                    res.append(dfs(pre+[sub(n1,n2)]+succ))\n",
    "                    res.append(dfs(pre+[mul(n1,n2)]+succ))\n",
    "                    if not is_zero(n2):res.append(dfs(pre+[dev(n1,n2)]+succ))\n",
    "                return any(res)\n",
    "            def get_nums(comb):\n",
    "                return [ [comb[0],1],[comb[1],1],[comb[2],1],[comb[3],1] ]\n",
    "            def arr(nums):\n",
    "                d=defaultdict(int)\n",
    "                for num in nums:d[num]+=1\n",
    "                def dfs2(p):\n",
    "                    if p==0:return [[num] for num in d.keys()]\n",
    "                    res=[]\n",
    "                    for arr in dfs2(p-1):\n",
    "                        for num in nums:\n",
    "                            temp=arr+[num]\n",
    "                            if len(list(filter(lambda x:x==num,arr)))<d[num]:res.append(temp)\n",
    "                    return res\n",
    "                return dfs2(len(nums)-1)\n",
    "\n",
    "            arrs=arr(cards)\n",
    "            for arr in arrs:\n",
    "                nums=get_nums(arr)\n",
    "                if dfs(nums):return True\n",
    "            return False\n",
    "        return lt679(cards)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def getgcd(a, b):\n",
    "    while b:\n",
    "        a, b = b, a % b\n",
    "    return a\n",
    "def simplify(num):\n",
    "    if num[0] == 0:\n",
    "        return (0,1)\n",
    "    if num[1] == 1:\n",
    "        return num\n",
    "    a = getgcd(num[0],num[1])\n",
    "    return (num[0]//a,num[1]//a)\n",
    "def add(num1,num2):\n",
    "    a, b = num1\n",
    "    c, d = num2\n",
    "    return simplify((a*d+c*b,b*d))\n",
    "def sub(num1,num2):\n",
    "    a, b = num1\n",
    "    c, d = num2\n",
    "    return simplify((a*d-c*b,b*d))\n",
    "def mul(num1,num2):\n",
    "    a, b = num1\n",
    "    c, d = num2\n",
    "    return simplify((a*c,b*d))\n",
    "def div(num1,num2):\n",
    "    a, b = num1\n",
    "    c, d = num2\n",
    "    return simplify((a*d,b*c))\n",
    "\n",
    "\n",
    "def func2(ans):\n",
    "    n = len(ans)\n",
    "    if n == 1:\n",
    "        return ans[0] == (24,1)\n",
    "    for i in range(n):\n",
    "        temp = ans[:i]+ans[i+1:]\n",
    "        for j in range(len(temp)):\n",
    "            num1 = ans[i]\n",
    "            num2 = temp[j]\n",
    "            a = add(num1,num2)\n",
    "            b = sub(num1, num2)\n",
    "            c = mul(num1, num2)\n",
    "            if func2([a]+temp[:j]+temp[j+1:]):return True\n",
    "            if func2([b]+temp[:j]+temp[j+1:]):return True\n",
    "            if func2([c]+temp[:j]+temp[j+1:]):return True\n",
    "            if num2[0] != 0:\n",
    "                d = div(num1,num2)\n",
    "                if func2([d]+temp[:j]+temp[j+1:]):return True\n",
    "    return False\n",
    "\n",
    "def func1(cards:List[int]):\n",
    "    ans = []\n",
    "    for i in range(len(cards)):\n",
    "        ans.append((cards[i],1))\n",
    "    return func2(ans)\n",
    "class Solution:\n",
    "    def judgePoint24(self, cards: List[int]) -> bool:\n",
    "        return func1(cards)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def judgePoint24(self, nums: List[int]) -> bool:\n",
    "        queue = deque([nums])\n",
    "        EPS = 0.0001\n",
    "        \n",
    "        seen = set()\n",
    "        \n",
    "        while queue:\n",
    "            current_state = queue.popleft()\n",
    "\n",
    "            if len(current_state) == 1 and abs(current_state[0] - 24.0) <= EPS:\n",
    "                return True\n",
    "            \n",
    "            seen.add(tuple(current_state))\n",
    "            for i in range(len(current_state)):\n",
    "                without_i = current_state[:i] + current_state[i+1:]\n",
    "                for j in range(len(without_i)):\n",
    "                    x, y = current_state[i], without_i[j]\n",
    "                    \n",
    "                    next_state = without_i[:j] + without_i[j+1:]\n",
    "                    next_values = [x + y, x - y, y - x, x * y]\n",
    "                    \n",
    "                    if y != 0:\n",
    "                        next_values.append(x / y)\n",
    "                    \n",
    "                    if x != 0:\n",
    "                        next_values.append(y / x)\n",
    "                    \n",
    "                    for val in next_values:\n",
    "                        if tuple(next_state + [val]) not in seen:\n",
    "                            queue.append(next_state + [val])\n",
    "                            seen.add(tuple(next_state + [val]))\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m = len(mat)\n",
    "        n = len(mat[0])\n",
    "        zero = [(i,j) for i in range(m) for j in range(n) if mat[i][j]==0]\n",
    "        used = set(zero)\n",
    "        q = collections.deque(zero)\n",
    "        while q:\n",
    "            i, j = q.popleft()\n",
    "            for ni,nj in [(i+1,j),(i-1,j),(i,j+1),(i,j-1)]:\n",
    "                if 0<=ni<m and 0<=nj<n and (ni,nj) not in used:\n",
    "                    used.add((ni,nj))\n",
    "                    q.append((ni,nj))\n",
    "                    mat[ni][nj] = mat[i][j]+1\n",
    "\n",
    "        return mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        dq = deque()\n",
    "        vis = set()\n",
    "        m,n  = len(mat), len(mat[0])\n",
    "        ans = mat.copy()\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    dq.append((i, j, 0))\n",
    "                    vis.add((i, j))\n",
    "\n",
    "        while dq:\n",
    "            x, y, val = dq[0]\n",
    "            ans[x][y] = val\n",
    "            dq.popleft()\n",
    "            for dx, dy in ((0,1), (1,0), (0,-1), (-1,0)):\n",
    "                nx, ny = x + dx, y + dy\n",
    "                if 0 <= nx < m and 0 <= ny < n and (nx, ny) not in vis:\n",
    "                    dq.append((nx, ny, val+1))\n",
    "                    vis.add((nx, ny))\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m,n = len(mat),len(mat[0])\n",
    "        queue = []\n",
    "        seen = set()\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j]==0: \n",
    "                    queue.append((i,j))\n",
    "                    seen.add((i,j))\n",
    "        queue = collections.deque(queue)\n",
    "        while queue:\n",
    "            # print(queue)\n",
    "            i,j = queue.popleft()\n",
    "            for ni,nj in (i-1,j),(i+1,j),(i,j-1),(i,j+1):\n",
    "                if ni>=0 and ni<m and nj>=0 and nj<n and (ni,nj) not in seen:\n",
    "                    mat[ni][nj] = mat[i][j]+1\n",
    "                    queue.append((ni,nj))\n",
    "                    seen.add((ni,nj))\n",
    "        return mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        # 不出意外的超时了\n",
    "        # n=len(mat)\n",
    "        # m=len(mat[0])\n",
    "        # # result[n][m]\n",
    "        # result=[[0]*m for _ in range(n)]\n",
    "        # def bfs(i,j):\n",
    "        #     queue=[(i,j,0)]\n",
    "        #     while queue:\n",
    "        #         node=queue.pop(0)\n",
    "        #         i,j,h=node[0],node[1],node[2]\n",
    "        #         if mat[i][j]==0:\n",
    "        #             return h\n",
    "        #         else:\n",
    "        #             if i+1<m:\n",
    "        #                 queue.append((i+1,j,h+1))\n",
    "        #             if 0<=i-1:\n",
    "        #                 queue.append((i-1,j,h+1))\n",
    "        #             if j+1<m:\n",
    "        #                 queue.append((i,j+1,h+1))\n",
    "        #             if 0<=j-1:\n",
    "        #                 queue.append((i,j-1,h+1))\n",
    "\n",
    "        # for i in range(n):\n",
    "        #     for j in range(m):\n",
    "        #         if mat[i][j]!=0: # mat[i][j]=0就不需要操作了\n",
    "        #             result[i][j]=bfs(i,j)\n",
    "        # return result\n",
    "\n",
    "\n",
    "        # 1）真正有效的bfs\n",
    "        # 但在实际的题目中，我们会有不止一个0。我们会想，要是我们可以把这些0 看成一个整体好了。有了这样的想法，我们可以添加一个「超级零」，它与矩阵中所有的0相连，这样的话，任意一个1到它最近的0的距离，会等于这个1到「超级零」的距离减去一。\n",
    "        # 由于我们只有一个「超级零」，我们就以它为起点进行广度优先搜索。这个「超级零」只和矩阵中的0相连，所以在广度优先搜索的第一步中，「超级零」会被弹出队列，而所有的0会被加入队列，它们到「超级零」的距离为1。\n",
    "        # 这就等价于：一开始我们就将所有的0加入队列，它们的初始距离为0。这样以来，在广度优先搜索的过程中，我们每遇到一个1，就得到了它到「超级零」的距离减去一，也就是 这个1到最近的0的距离。 \n",
    "        # m,n=len(mat),len(mat[0]) # [m,n]\n",
    "        # dist=[[0]*n for _ in range(m)]\n",
    "        # zeroes_pos=[(i,j) for i in range(m) for j in range(n) if mat[i][j]==0]\n",
    "        # # 将所有的0添加到初始队列中\n",
    "        # q=collections.deque(zeroes_pos)\n",
    "        # seen=set(zeroes_pos) # 找过的点不需要再找了\n",
    "        # # 广度优先搜索\n",
    "        # while q:\n",
    "        #     i,j=q.popleft()\n",
    "        #     for ni,nj in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]:\n",
    "        #         if 0<=ni<m and 0<=nj<n and (ni,nj) not in seen:\n",
    "        #             dist[ni][nj]=dist[i][j]+1\n",
    "        #             q.append((ni,nj))\n",
    "        #             seen.add((ni,nj))\n",
    "        # return dist\n",
    "\n",
    "        # 动态规划！！！\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        # 初始化动态规划的数组，所有的距离值都设置为一个很大的数\n",
    "        dist = [[10**9] * n for _ in range(m)]\n",
    "        # 如果 (i, j) 的元素为 0，那么距离为 0\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    dist[i][j] = 0\n",
    "        # 只有 水平向左移动 和 竖直向上移动，注意动态规划的计算顺序\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if i - 1 >= 0:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1)\n",
    "                if j - 1 >= 0:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i][j - 1] + 1)\n",
    "        # 只有 水平向左移动 和 竖直向下移动，注意动态规划的计算顺序\n",
    "        for i in range(m - 1, -1, -1):\n",
    "            for j in range(n):\n",
    "                if i + 1 < m:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i + 1][j] + 1)\n",
    "                if j - 1 >= 0:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i][j - 1] + 1)\n",
    "        # 只有 水平向右移动 和 竖直向上移动，注意动态规划的计算顺序\n",
    "        for i in range(m):\n",
    "            for j in range(n - 1, -1, -1):\n",
    "                if i - 1 >= 0:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i - 1][j] + 1)\n",
    "                if j + 1 < n:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i][j + 1] + 1)\n",
    "        # 只有 水平向右移动 和 竖直向下移动，注意动态规划的计算顺序\n",
    "        for i in range(m - 1, -1, -1):\n",
    "            for j in range(n - 1, -1, -1):\n",
    "                if i + 1 < m:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i + 1][j] + 1)\n",
    "                if j + 1 < n:\n",
    "                    dist[i][j] = min(dist[i][j], dist[i][j + 1] + 1)\n",
    "        return dist\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        nrow = len(mat)\n",
    "        ncol = len(mat[0])\n",
    "\n",
    "        def bfs(i, j):\n",
    "            q = deque()\n",
    "            visited = set()\n",
    "\n",
    "            q.append((i,j))\n",
    "            visited.add((i,j))\n",
    "\n",
    "            step = 0\n",
    "            while len(q)>0:\n",
    "                N = len(q)\n",
    "                for _ in range(N):\n",
    "                    ci, cj = q.popleft()\n",
    "                    if mat[ci][cj]==0:\n",
    "                        return step\n",
    "                    \n",
    "                    for di, dj in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n",
    "                        if ci+di<0 or ci+di>=nrow or cj+dj<0 or cj+dj>=ncol:\n",
    "                            continue\n",
    "                        if (ci+di,cj+dj) not in visited:\n",
    "                            q.append((ci+di,cj+dj))\n",
    "                            visited.add((ci+di,cj+dj))\n",
    "                step += 1\n",
    "        \n",
    "        ans = [[0 for _ in range(ncol)] for _ in range(nrow)]\n",
    "        for i in range(nrow):\n",
    "            for j in range(ncol):\n",
    "                ans[i][j] = bfs(i, j)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        dist = [[0] * n for _ in range(m)]\n",
    "        zeroes_pos = [(i, j) for i in range(m) for j in range(n) if mat[i][j] == 0]\n",
    "        # 将所有的 0 添加进初始队列中\n",
    "        q = collections.deque(zeroes_pos)\n",
    "        seen = set(zeroes_pos)\n",
    "\n",
    "        # 广度优先搜索\n",
    "        while q:\n",
    "            i, j = q.popleft()\n",
    "            for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:\n",
    "                if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen:\n",
    "                    dist[ni][nj] = dist[i][j] + 1\n",
    "                    q.append((ni, nj))\n",
    "                    seen.add((ni, nj))\n",
    "        \n",
    "        return dist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        dirs = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n",
    "        zeros = set()\n",
    "        ans = []\n",
    "        for r in range(m):\n",
    "            for c in range(n):\n",
    "                if mat[r][c] == 0:\n",
    "                    zeros.add((r, c))\n",
    "                else:\n",
    "                    mat[r][c] = -1\n",
    "        d = zeros\n",
    "        step = 1\n",
    "        while d:\n",
    "            nex = []\n",
    "            for x, y in d:\n",
    "                for dx, dy in dirs:\n",
    "                    cx, cy = x+dx, y+dy\n",
    "                    if cx<0 or cx>=m or cy<0 or cy>=n:\n",
    "                        continue\n",
    "                    if mat[cx][cy] == -1:\n",
    "                        mat[cx][cy] = step\n",
    "                        nex.append((cx, cy))\n",
    "            d = nex\n",
    "            step += 1\n",
    "        return mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        edge = set()\n",
    "        res = set()\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    edge.add((i, j))\n",
    "                else:\n",
    "                    res.add((i, j))\n",
    "        \n",
    "        dis = [-1, 0, 1, 0, -1]\n",
    "        r = 1\n",
    "        while res:\n",
    "            new = set()\n",
    "            for i, j in edge:\n",
    "                for k in range(4):\n",
    "                    x = i + dis[k]\n",
    "                    y = j + dis[k+1]\n",
    "                    if (x, y) in res:\n",
    "                        new.add((x, y))\n",
    "                        mat[x][y] = r\n",
    "            res -= new\n",
    "            edge = new\n",
    "            r += 1\n",
    "        \n",
    "        return mat\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        res = [[0] * n for _ in range(m)]\n",
    "        vis = set()\n",
    "        deque = collections.deque()\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    vis.add((i, j))\n",
    "                    deque.append((i, j))\n",
    "\n",
    "        while deque:\n",
    "            i, j = deque.popleft()\n",
    "            for ni, nj in [(i-1, j), (i+1, j), (i, j-1), (i, j+1)]:\n",
    "                if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in vis:\n",
    "                    res[ni][nj] = res[i][j] + 1\n",
    "                    deque.append((ni, nj))\n",
    "                    vis.add((ni, nj))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat):\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        distance = [[0] * n for _ in range(m)]\n",
    "        queue = [(i, j) for i in range(m) for j in range(n) if mat[i][j] == 0]\n",
    "        recode = set(queue)\n",
    "\n",
    "        while queue:\n",
    "            i, j = queue.pop(0)\n",
    "            for x, y in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:\n",
    "                if 0 <= x < m and 0 <= y < n and (x, y) not in recode:\n",
    "                    distance[x][y] = distance[i][j] + 1\n",
    "                    queue.append((x, y))\n",
    "                    recode.add((x, y))\n",
    "        return distance\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        res = [[0] * n for _ in range(m)]\n",
    "        zero_pos = []\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    zero_pos.append((i, j))\n",
    "        q = collections.deque(zero_pos)\n",
    "        seen = set(zero_pos)\n",
    "        while q:\n",
    "            i, j = q.popleft()\n",
    "            for di, dj in [(-1, 0), (1, 0), (0, 1), (0, -1)]:\n",
    "                newi, newj = i+di, j+dj\n",
    "                if 0<=newi<m and 0<=newj<n and (newi, newj) not in seen:\n",
    "                    res[newi][newj] = res[i][j] + 1\n",
    "                    q.append((newi, newj))\n",
    "                    seen.add((newi, newj))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m=len(mat)\n",
    "        n=len(mat[0])\n",
    "        dist=[[0 for i in range(n)] for j in range(m)]\n",
    "        zeroes_pos=[(i,j) for i in range(m) for j in range(n) if mat[i][j]==0]\n",
    "        dx=[1,0,-1,0]\n",
    "        dy=[0,-1,0,1]\n",
    "        st=set(zeroes_pos)\n",
    "        q=collections.deque(zeroes_pos)\n",
    "        while q:\n",
    "            x,y=q.popleft()\n",
    "            for i in range(4):\n",
    "                a=x+dx[i]\n",
    "                b=y+dy[i]\n",
    "                if a<0 or a>=m or b<0 or b>=n or (a,b) in st:\n",
    "                    continue\n",
    "                dist[a][b]=dist[x][y]+1\n",
    "                st.add((a,b))\n",
    "                q.append((a,b))\n",
    "        return dist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        n = len(mat)\n",
    "        m = len(mat[0])\n",
    "        res = [[0]*m for _ in range(n)]\n",
    "        # for i in range(n):\n",
    "        #     for j in range(m):\n",
    "        #         if mat[i][j] == 0:\n",
    "        #             res[i][j] = 0\n",
    "        # for i in range(n):\n",
    "        #     for j in range(m):\n",
    "        #         if i > 0:\n",
    "        #             res[i][j] = min(res[i-1][j]+1, res[i][j])\n",
    "        #         if j > 0:\n",
    "        #             res[i][j] = min(res[i][j-1]+1, res[i][j])\n",
    "        # for i in range(n-1, -1, -1):\n",
    "        #     for j in range(m-1, -1, -1):\n",
    "        #         if i < n-1:\n",
    "        #             res[i][j] = min(res[i+1][j]+1, res[i][j])\n",
    "        #         if j < m-1:\n",
    "        #             res[i][j] = min(res[i][j+1]+1, res[i][j])\n",
    "        # return res\n",
    "        q = deque()\n",
    "        visited = set()\n",
    "        for i in range(n):\n",
    "            for j in range(m):\n",
    "                if mat[i][j] == 0:\n",
    "                    q.append((i,j,0))\n",
    "                    visited.add((i,j))\n",
    "        while q:\n",
    "            x, y, d = q.popleft()\n",
    "            res[x][y] = d\n",
    "            if x-1>=0 and (x-1, y) not in visited:\n",
    "                q.append((x-1, y, d+1))\n",
    "                visited.add((x-1, y))\n",
    "            if x+1<n and (x+1, y) not in visited:\n",
    "                q.append((x+1, y, d+1))\n",
    "                visited.add((x+1, y))\n",
    "            if y-1>=0 and (x, y-1) not in visited:\n",
    "                q.append((x, y-1, d+1))\n",
    "                visited.add((x, y-1))\n",
    "            if y+1<m and (x, y+1) not in visited:\n",
    "                q.append((x, y+1, d+1))\n",
    "                visited.add((x, y+1))\n",
    "        return res\n",
    "          \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m,n=len(mat),len(mat[0])\n",
    "        dp=[[0 for i in range(n)] for j in range(m)]\n",
    "        rds=[(0,1),(0,-1),(1,0),(-1,0)]\n",
    "        st=set()\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if(mat[i][j]==0):\n",
    "                    for x,y in rds:\n",
    "                        ni,nj=i+x,j+y\n",
    "                        if 0<=ni<m and 0<=nj<n and mat[ni][nj]==1:\n",
    "                            mat[ni][nj]=-1\n",
    "                            dp[ni][nj]=1\n",
    "                            st.add((ni,nj))\n",
    "        t=2\n",
    "        print(dp)\n",
    "        print(st)\n",
    "        while(st):\n",
    "            nst=set()\n",
    "            for i,j in st:\n",
    "                for x,y in rds:\n",
    "                    ni,nj=i+x,j+y\n",
    "                    if 0<=ni<m and 0<=nj<n and mat[ni][nj]==1:\n",
    "                        mat[ni][nj]=-1\n",
    "                        dp[ni][nj]=t\n",
    "                        nst.add((ni,nj))\n",
    "            t+=1\n",
    "            st=nst\n",
    "        return dp\n",
    "    \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "\n",
    "        # bfs\n",
    "        m = len(mat)\n",
    "        n = len(mat[0])\n",
    "        d = [[-1 for _ in range(n)] for _ in range(m)]\n",
    "\n",
    "        cur = []\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    d[i][j] = 0\n",
    "\n",
    "                    cur.append((i,j))\n",
    "\n",
    "        # print(cur)\n",
    "        DIRS = ((0, 1), (0, -1), (1, 0), (-1, 0))\n",
    "        step = 0\n",
    "        while cur:\n",
    "            next = set()\n",
    "            step += 1\n",
    "            for i, j in cur:\n",
    "                for di, dj in DIRS:\n",
    "\n",
    "                    ni = i + di\n",
    "                    nj = j + dj\n",
    "\n",
    "                    if 0 <= ni < m and 0 <= nj < n and d[ni][nj] == -1:\n",
    "                        d[ni][nj] = step\n",
    "                        next.add((ni, nj))\n",
    "            \n",
    "            cur = next\n",
    "        \n",
    "        return d\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(mat), len(mat[0])\n",
    "        zero_pos = []\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    zero_pos.append((i, j))\n",
    "        q = collections.deque(zero_pos)\n",
    "        seen = set(zero_pos)\n",
    "        res = [[0] * n for _ in range(m)]\n",
    "        while q:\n",
    "            i, j = q.popleft()\n",
    "            for di, dj in [(-1, 0), (1, 0), (0, -1), (0, 1)]:\n",
    "                newi, newj = i+di, j+dj\n",
    "                if 0<=newi<m and 0<=newj<n and (newi, newj) not in seen:\n",
    "                    res[newi][newj] = res[i][j] + 1\n",
    "                    q.append((newi, newj))\n",
    "                    seen.add((newi, newj))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        if not mat:\n",
    "            return mat\n",
    "        m,n = len(mat),len(mat[0])\n",
    "        distance = [[0] * n for _ in range(m)]\n",
    "        queue = [(i,j) for i in range(m) for j in range(n) if mat[i][j] == 0]\n",
    "\n",
    "        recode = set(queue)\n",
    "\n",
    "        while queue:\n",
    "            i,j = queue.pop(0)\n",
    "            for x,y in [(i-1,j),(i+1,j),(i,j-1),(i,j+1)]:\n",
    "                if 0<=x<m and 0<=y<n and (x,y) not in recode:\n",
    "                    distance[x][y] = distance[i][j] + 1\n",
    "                    queue.append((x,y))\n",
    "                    recode.add((x,y))\n",
    "        return distance\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        m = len(mat)\n",
    "        n = len(mat[0])\n",
    "        offset_list = [(0, 1), (1, 0), (-1, 0), (0, -1)]\n",
    "\n",
    "        queue = deque()\n",
    "        result = [[0] * n for _ in range(m)]\n",
    "        used = set()\n",
    "\n",
    "        for i in range(m):\n",
    "            for j in range(n):\n",
    "                if mat[i][j] == 0:\n",
    "                    queue.append((i, j))\n",
    "                else:\n",
    "                    result[i][j] = float('inf')\n",
    "\n",
    "        while queue:\n",
    "            i, j = queue.popleft()\n",
    "            for offset_i, offset_j in offset_list:\n",
    "                next_i = i + offset_i\n",
    "                next_j = j + offset_j\n",
    "                if 0 <= next_i < m and 0 <= next_j < n and (next_i, next_j) not in used:\n",
    "                    used.add((next_i, next_j))\n",
    "                    queue.append((next_i, next_j))\n",
    "                    if result[next_i][next_j] > result[i][j] + 1:\n",
    "                        result[next_i][next_j] = result[i][j] + 1\n",
    "        \n",
    "        return result\n",
    "                    \n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        dist = [[0] * n for _ in range(m)]\n",
    "        zeroes_pos = [(i, j) for i in range(m) for j in range(n) if matrix[i][j] == 0]\n",
    "        # 将所有的 0 添加进初始队列中\n",
    "        # q = collections.deque(zeroes_pos)\n",
    "        q = zeroes_pos\n",
    "        seen = set(zeroes_pos)\n",
    "\n",
    "        # 广度优先搜索\n",
    "        while q:\n",
    "            i, j = q.pop(0)\n",
    "            for ni, nj in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:\n",
    "                if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen:\n",
    "                    dist[ni][nj] = dist[i][j] + 1\n",
    "                    q.append((ni, nj))\n",
    "                    seen.add((ni, nj))\n",
    "        \n",
    "        return dist\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:\n",
    "        result = [[-1 for _ in range(len(mat[0]))] for _ in range(len(mat))]\n",
    "        zero_idx_lst = []\n",
    "        for i in range(len(mat)):\n",
    "            for j in range(len(mat[0])):\n",
    "                if mat[i][j] == 0:\n",
    "                    zero_idx_lst.append((i, j))\n",
    "        flag = 0\n",
    "        direct_lst = [(0, 1), (0, -1), (1, 0), (-1, 0)]\n",
    "        while zero_idx_lst:\n",
    "            print(zero_idx_lst)\n",
    "            tmp_lst = set()\n",
    "            for (i, j) in zero_idx_lst:\n",
    "                result[i][j] = flag\n",
    "            for (i, j) in zero_idx_lst:\n",
    "                for (gap_x, gap_y) in direct_lst:\n",
    "                    new_x, new_y = i + gap_x, j + gap_y\n",
    "                    if 0 <= new_x < len(mat) and 0 <= new_y < len(mat[0]) and result[new_x][new_y] == -1:\n",
    "                        tmp_lst.add((new_x, new_y))\n",
    "            zero_idx_lst = list(tmp_lst)[:]\n",
    "            flag += 1\n",
    "        return result\n",
    "\n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        left, right = 0, 0\n",
    "        current = nums[left]\n",
    "        if current >= target:\n",
    "            return 1\n",
    "        min_size = len(nums) + 1\n",
    "\n",
    "        while right < len(nums) - 1:\n",
    "            while current < target and right < len(nums) - 1:\n",
    "                right += 1\n",
    "                current += nums[right]\n",
    "                print(\"add\", left, right, current)\n",
    "            if current >= target:\n",
    "                min_size = min_size if min_size < right - left + 1 else right - left + 1\n",
    "            while current >= target and left < right:\n",
    "                left += 1\n",
    "                current -= nums[left-1]\n",
    "                print(\"reduce\", left, right, current)\n",
    "                if current >= target:\n",
    "                    min_size = min_size if min_size < right - left + 1 else right - left + 1\n",
    "                if min_size == 1:\n",
    "                    return min_size\n",
    "        return min_size if min_size != len(nums) + 1 else 0\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def minSubArrayLen(self, target: int, nums: List[int]) -> int:\n",
    "        n = len(nums)\n",
    "\n",
    "        # 累加数组\n",
    "        addNums = []\n",
    "        total = 0\n",
    "        for num in nums:\n",
    "            if num >= target:\n",
    "                return 1\n",
    "            total += num\n",
    "            addNums.append(total)\n",
    "        \n",
    "        # 正整数数组，没有负数\n",
    "        if total < target:\n",
    "            return 0\n",
    "        elif total == target:\n",
    "            return n\n",
    "        \n",
    "        # 连续子数组包含最后一个数组时\n",
    "        # 二分查找 diff 所在的索引 index\n",
    "        diff = total - target\n",
    "        index = bisect.bisect_right(addNums, diff)\n",
    "        rs = n - index  # 从 index ~ n -1\n",
    "\n",
    "        leftTotal = 0 if index == 0 else addNums[index - 1]\n",
    "\n",
    "        for i in range(n - 2, -1, -1):\n",
    "            if addNums[i] < target:\n",
    "                break\n",
    "            while addNums[i] - leftTotal < target:\n",
    "                index -= 1\n",
    "                leftTotal = 0 if index == 0 else addNums[index - 1]\n",
    "            rs = min(rs, i - index + 1)\n",
    "        \n",
    "        return rs\n",
    "\n",
    "        \n",
    "\n",
    "        \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(arr)\n",
    "        keys = sorted(count)\n",
    "        \n",
    "        ans = 0\n",
    "        \n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                    \n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)  # 频率\n",
    "        keys = sorted(count)  # key排序\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) // 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) // 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) // 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return ans % MOD"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "class Solution:\n",
    "    def threeSumMulti(self, A: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(arr)\n",
    "        keys = sorted(count)\n",
    "        \n",
    "        ans = 0\n",
    "        \n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                    \n",
    "        return int(ans % MOD)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        cnt = Counter(arr)\n",
    "        arr.sort()\n",
    "        n = len(arr)\n",
    "        mod = 10**9+7\n",
    "        # visit = set()\n",
    "        \n",
    "        ans = 0\n",
    "        for i in range(n-2):\n",
    "            cnt[arr[i]] -= 1\n",
    "            g = cnt.copy()\n",
    "            for j in range(i+1,n-1):\n",
    "                # print(g,cnt)\n",
    "                g[arr[j]] -= 1\n",
    "                t = target - arr[i] - arr[j]\n",
    "                if t < 0:\n",
    "                    break\n",
    "                # com = tuple(sorted([arr[i],arr[j],t]))\n",
    "                # print(arr[i],arr[j],t,cnt[t])\n",
    "                ans += g[t]%mod\n",
    "                # if g[t]:\n",
    "                #     ans += g[t]\n",
    "                #     ans %= mod\n",
    "                    # visit.add(com)\n",
    "                    # print(arr[i],arr[j],t,cnt[t])\n",
    "                # if t != arr[i] and t != arr[j]:\n",
    "                #     ans += cnt[t]\n",
    "                # elif t == arr[i] and t == arr[j]:\n",
    "                #     ans += cnt[t] - 2\n",
    "                # else:\n",
    "                #     ans += cnt[t] - 1\n",
    "                # ans %= mod\n",
    "        return ans%mod\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSumMulti(self, arr: List[int], target: int) -> int:\n",
    "        c = Counter(arr)\n",
    "        hashSet = set()\n",
    "        res = 0\n",
    "        for i in c:\n",
    "            for j in c:\n",
    "                k = target -i -j\n",
    "                if k in c:\n",
    "                    if \" \".join([str(s) for s in sorted([i,j,k])]) in hashSet:\n",
    "                        continue\n",
    "                    if i == j == k and c[i] >=3:\n",
    "                        res += math.comb(c[i], 3)\n",
    "                    elif i == j != k and c[i] >= 2:\n",
    "                        res += math.comb(c[i], 2) * c[k]\n",
    "                    elif i == k != j and c[i] >= 2:\n",
    "                        res += math.comb(c[i], 2) * c[j]\n",
    "                    elif j == k != i and c[j] >= 2:\n",
    "                        res += math.comb(c[j], 2) * c[i]\n",
    "                    elif i != j != k:\n",
    "                        res += c[i] * c[j] * c[k]\n",
    "                    res %= 10 ** 9 + 7\n",
    "                    hashSet.add(\" \".join([str(s) for s in sorted([i,j,k])]))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def threeSumMulti(self, A, target):\n",
    "        MOD = 10**9 + 7\n",
    "        count = collections.Counter(A)\n",
    "        print(count)\n",
    "        keys = sorted(count)\n",
    "\n",
    "        ans = 0\n",
    "\n",
    "        # Now, let's do a 3sum on \"keys\", for i <= j <= k.\n",
    "        # We will use count to add the correct contribution to ans.\n",
    "        for i, x in enumerate(keys):\n",
    "            T = target - x\n",
    "            j, k = i, len(keys) - 1\n",
    "            while j <= k:\n",
    "                y, z = keys[j], keys[k]\n",
    "                if y + z < T:\n",
    "                    j += 1\n",
    "                elif y + z > T:\n",
    "                    k -= 1\n",
    "                else: # x+y+z == T, now calculate the size of the contribution\n",
    "                    if i < j < k:\n",
    "                        ans += count[x] * count[y] * count[z]\n",
    "                    elif i == j < k:\n",
    "                        ans += count[x] * (count[x] - 1) / 2 * count[z]\n",
    "                    elif i < j == k:\n",
    "                        ans += count[x] * count[y] * (count[y] - 1) / 2\n",
    "                    else:  # i == j == k\n",
    "                        ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6\n",
    "\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "\n",
    "        return int(ans % MOD)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#\r\n",
    "# @lc app=leetcode.cn id=15 lang=python3\r\n",
    "#\r\n",
    "# [15] 三数之和\r\n",
    "#\r\n",
    "# https://leetcode-cn.com/problems/3sum/description/\r\n",
    "#\r\n",
    "# algorithms\r\n",
    "# Medium (20.97%)\r\n",
    "# Total Accepted:    38K\r\n",
    "# Total Submissions: 181K\r\n",
    "# Testcase Example:  '[-1,0,1,2,-1,-4]'\r\n",
    "#\r\n",
    "# 给定一个包含 n 个整数的数组 nums，判断 nums 中是否存在三个元素 a，b，c ，使得 a + b + c = 0\r\n",
    "# ？找出所有满足条件且不重复的三元组。\r\n",
    "# \r\n",
    "# 注意：答案中不可以包含重复的三元组。\r\n",
    "# \r\n",
    "# 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]，\r\n",
    "# \r\n",
    "# 满足要求的三元组集合为：\r\n",
    "# [\r\n",
    "# ⁠ [-1, 0, 1],\r\n",
    "# ⁠ [-1, -1, 2]\r\n",
    "# ]\r\n",
    "# \r\n",
    "# \r\n",
    "#\r\n",
    "class Solution:\r\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\r\n",
    "        nums = sorted(nums)\r\n",
    "        l = len(nums)\r\n",
    "        r = set()\r\n",
    "        for c in range(l):\r\n",
    "            a = c+1\r\n",
    "            b = l-1\r\n",
    "            sum = -nums[c]\r\n",
    "\r\n",
    "            while a < b:\r\n",
    "                if nums[a] + nums[b] > sum:\r\n",
    "                    b -= 1\r\n",
    "                elif nums[a] + nums[b] < sum:\r\n",
    "                    a += 1\r\n",
    "                else:\r\n",
    "                    r.add(tuple(sorted([nums[a],nums[b],nums[c]])))\r\n",
    "                    a += 1\r\n",
    "                    b -= 1\r\n",
    "\r\n",
    "        return [list(t) for t in r]\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "        \r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "\n",
    "    def __init__(self):\n",
    "        self.result = []\n",
    "\n",
    "    def threeSum(self, nums):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        cp = sorted(list(nums))\n",
    "        # print(cp)\n",
    "        for i in range(len(cp) - 2):\n",
    "            # print(cp[i])\n",
    "            # print(cp[i+1:])\n",
    "            if i > 0 and cp[i] == cp[i-1]:\n",
    "                continue\n",
    "            temp = []\n",
    "            self.twoSum(cp[i+1:], temp, -cp[i])\n",
    "            for e in temp:\n",
    "                e.append(cp[i])\n",
    "            self.result = self.result + temp\n",
    "\n",
    "        return self.getResult()\n",
    "\n",
    "\n",
    "    def twoSum(self, nums, result, target):\n",
    "        left = 0\n",
    "        right = len(nums) - 1\n",
    "        while left < right:\n",
    "            s = nums[left] + nums[right]\n",
    "            if s < target:\n",
    "                left += 1\n",
    "            elif s > target:\n",
    "                right -= 1\n",
    "            else:\n",
    "                result.append([nums[left], nums[right]])\n",
    "                left += 1\n",
    "                right -= 1\n",
    "\n",
    "\n",
    "    def getResult(self):\n",
    "        ret = self.result\n",
    "        threeret = set()\n",
    "        rrr = []\n",
    "        for r in ret:\n",
    "            h = \"\".join(map(lambda x: str(x), r))\n",
    "            if not h in threeret:\n",
    "                rrr.append(r)\n",
    "                threeret.add(h)\n",
    "        return rrr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        dataList = sorted(nums)\n",
    "        result = set([])\n",
    "        for index in range(len(dataList)-2):\n",
    "            index1 = index+1\n",
    "            index2 = len(dataList)-1\n",
    "            if dataList[index]>0:\n",
    "                break\n",
    "            if index>0 and dataList[index]==dataList[index-1]:\n",
    "                continue\n",
    "            while index1<index2:\n",
    "                sum_2 = dataList[index1]+dataList[index2]\n",
    "                if dataList[index]+dataList[index1]>0:\n",
    "                    break\n",
    "                if sum_2==-dataList[index]:\n",
    "                    result.add((dataList[index],dataList[index1],dataList[index2]))\n",
    "                    index1+=1\n",
    "                    index2-=1\n",
    "                elif sum_2>-dataList[index]:\n",
    "                    index2-=1\n",
    "                else:\n",
    "                    index1+=1\n",
    "        return list(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        if len(nums) < 3:\n",
    "            return []\n",
    "\n",
    "        res = set()\n",
    "        nums.sort()\n",
    "        for i in range(len(nums)):\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "\n",
    "            j, k = i + 1, len(nums)-1\n",
    "\n",
    "            while j < k:\n",
    "                if nums[i] + nums[j] + nums[k] == 0:\n",
    "                    res.add((nums[i], nums[j], nums[k]))\n",
    "                    j += 1\n",
    "                    k -= 1\n",
    "                elif nums[i] + nums[j] + nums[k] > 0:\n",
    "                    k -= 1\n",
    "                else:\n",
    "                    j += 1\n",
    "\n",
    "        return list(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: list[int]) -> list[list[int]]:\n",
    "        nums.sort()\n",
    "        res = set()\n",
    "        n = len(nums)\n",
    "        for i in range(n-2):\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            if nums[i] > 0:\n",
    "                break\n",
    "            l = i + 1\n",
    "            r = n - 1\n",
    "            while l < r:\n",
    "                if nums[i] + nums[l] + nums[r] < 0:\n",
    "                    l += 1\n",
    "                elif nums[i] + nums[l] + nums[r] > 0:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    res.add(tuple((nums[i], nums[l], nums[r])))\n",
    "                    while l < r and nums[l] == nums[l+1]:\n",
    "                        l += 1\n",
    "                    while l < r and nums[r] == nums[r-1]:\n",
    "                        r -= 1\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "        return list(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = []\n",
    "        nums.sort()\n",
    "        for i in range(len(nums) - 2):\n",
    "            if nums[i] > 0 :\n",
    "                break\n",
    "            #i != j、i != k 且 j != k,需要去重\n",
    "            if i > 0 and nums[i] == nums[i-1]:\n",
    "                continue\n",
    "            #双指针\n",
    "            left , right = i + 1, len(nums) - 1\n",
    "            while left < right:\n",
    "                total = nums[i] + nums[left] + nums[right]\n",
    "                if total < 0:\n",
    "                    left += 1\n",
    "                elif total > 0 :\n",
    "                    right -= 1\n",
    "                else:\n",
    "                    result.append([nums[i],nums[left],nums[right]])\n",
    "                    while left < right and nums[left] == nums[left+1]:\n",
    "                        left+=1\n",
    "                    while left < right and  nums[right] == nums[right - 1]:\n",
    "                        right-=1\n",
    "                    left += 1\n",
    "                    right -=1\n",
    "        return result\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        nums.sort()\n",
    "        result = set()\n",
    "        if n <= 2:\n",
    "            return []\n",
    "        for i in range(n-2):\n",
    "            left = i + 1\n",
    "            right = n - 1\n",
    "            while left < right:\n",
    "                if nums[left] + nums[right] + nums[i] == 0:\n",
    "                    result1 = [nums[left],nums[right],nums[i]]\n",
    "                    result1.sort()\n",
    "                    result1 = tuple(result1)\n",
    "                    result.add(result1)\n",
    "                    left +=1\n",
    "                    right -= 1\n",
    "                elif nums[left] + nums[right] + nums[i] < 0:\n",
    "                    left += 1\n",
    "                else:\n",
    "                    right -= 1\n",
    "        return list(result) #慢"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        ans = set()\n",
    "        for i in range(len(nums)-2):\n",
    "            if nums[i] > 0: break\n",
    "            l = i + 1\n",
    "            r = len(nums)-1\n",
    "            while l < r:\n",
    "                if nums[l]+nums[r]+nums[i] == 0:\n",
    "                    ans.add((nums[i],nums[l],nums[r]))\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                elif nums[i]+nums[l]+nums[r] < 0:\n",
    "                    l += 1\n",
    "                else: r -= 1\n",
    "        return list(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def threeSum(self, nums: List[int]) -> List[List[int]]:\n",
    "        def twoSum(nums, target):\n",
    "            res = []\n",
    "            dic = {}\n",
    "            use_set = set()\n",
    "            for i,num in enumerate(nums):\n",
    "                if num not in dic:\n",
    "                    dic[target-num] = num\n",
    "                elif num not in use_set:\n",
    "                    res.append([target-num, num])\n",
    "                    use_set.add(num)\n",
    "\n",
    "            return res\n",
    "        nums.sort()\n",
    "        res = []\n",
    "        for i, n in enumerate(nums):\n",
    "            if i>0 and nums[i-1]==nums[i]:\n",
    "                continue\n",
    "            for twonum in twoSum(nums[i+1:], -n):\n",
    "                res.append([n]+twonum)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:\n",
    "        a, b = headA, headB\n",
    "        while a and b and a != b:\n",
    "            a = a.next\n",
    "            b = b.next\n",
    "        if a == b:\n",
    "            return a\n",
    "        if b == None:\n",
    "            headA, headB = headB, headA\n",
    "            a, b = b, a\n",
    "        a = headB\n",
    "        while a and b:\n",
    "            a = a.next\n",
    "            b = b.next\n",
    "        b = headA\n",
    "        while a and b:\n",
    "            if a == b:\n",
    "                return a\n",
    "            a = a.next\n",
    "            b = b.next\n",
    "        return None\n",
    "\n",
    "class Solution:\n",
    "    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:\n",
    "        nodeDic = set()\n",
    "        while headA:\n",
    "            nodeDic.add(headA)\n",
    "            headA = headA.next\n",
    "        while headB:\n",
    "            if headB in nodeDic:\n",
    "                return headB\n",
    "            headB = headB.next\n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:\n",
    "        node_temp = set()\n",
    "        p = headA\n",
    "        while(p):\n",
    "            node_temp.add(p)\n",
    "            p = p.next\n",
    "        p = headB\n",
    "        while(p):\n",
    "            if(p in node_temp):\n",
    "                return p\n",
    "            p = p.next\n",
    "        return None "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:\n",
    "        a = set()\n",
    "        while headA:\n",
    "            a.add(headA)\n",
    "            headA = headA.next\n",
    "        while headB:\n",
    "            if headB in a:\n",
    "                return headB\n",
    "            headB = headB.next\n",
    "        return None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:\n",
    "        curA = headA\n",
    "        dic = set()\n",
    "        while curA:\n",
    "            dic.add(curA)\n",
    "            curA = curA.next\n",
    "        # print(dic)\n",
    "        curB = headB\n",
    "        while curB:\n",
    "            if curB in dic:\n",
    "                return curB\n",
    "            curB = curB.next\n",
    "        return None\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:\n",
    "        seen=set()\n",
    "        while headA:\n",
    "            seen.add(headA)\n",
    "            headA=headA.next\n",
    "        while headB:\n",
    "            if headB in seen:\n",
    "                return headB\n",
    "            headB=headB.next\n",
    "        return  None\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:\n",
    "        p, q = headA, headB\n",
    "        res = []\n",
    "        res2 = set()\n",
    "        while p:\n",
    "            # res.append(p)\n",
    "            res2.add(p)\n",
    "            p = p.next\n",
    "        while q:\n",
    "            if q in res2:\n",
    "                return q\n",
    "            q = q.next\n",
    "        return None\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def maxA(self, N):\n",
    "        best = [0, 1]\n",
    "        for k in range(2, N+1):\n",
    "            best.append(max(best[x] * (k-x-1) for x in range(k-1)))\n",
    "            best[-1] = max(best[-1], best[-2] + 1) #addition\n",
    "        return best[N]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def maxA(self, N):\n",
    "        best = [0, 1, 2]\n",
    "        for k in range(3, N+1):\n",
    "            best.append(max(best[x] * (k-x-1) for x in range(k-2)))\n",
    "            best[-1] = max(best[-1], best[-2] + 1) #addition\n",
    "        return best[N]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def maxA(self, n: int) -> int:\n",
    "        best = [0, 1]\n",
    "        for k in range(2, n+1):\n",
    "            best.append(max(best[x] * (k-x-1) for x in range(k-1)))\n",
    "            best[-1] = max(best[-1], best[-2] + 1) #addition\n",
    "        return best[n]\n",
    "        \n",
    "    def maxA2(self, n: int) -> int:\n",
    "        best = [0, 1, 2, 3, 4, 5, 6, 9, 12,\n",
    "                16, 20, 27, 36, 48, 64, 81]\n",
    "        q = (n - 11) / 5 if n > 15 else 0\n",
    "        return best[n - 5*q] * 4**q"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        candidates=sorted(candidates)\n",
    "        path,res=[],[]\n",
    "        def dfs(startindex):\n",
    "            if sum(path)>target:\n",
    "                return\n",
    "            elif sum(path)==target:\n",
    "                res.append(path.copy())\n",
    "                return\n",
    "            set1=set()\n",
    "            for i in range(startindex,len(candidates)):\n",
    "                if candidates[i] in set1:\n",
    "                    continue\n",
    "                set1.add(candidates[i])\n",
    "                path.append(candidates[i])\n",
    "                dfs(i+1)\n",
    "                path.pop()\n",
    "        dfs(0)\n",
    "        return res\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:\n",
    "        def dfs(idx, s):\n",
    "            if s > target or s + sum(candidates[idx:]) < target:\n",
    "                return\n",
    "            if s == target:\n",
    "                res.add(tuple(path[:]))\n",
    "                return\n",
    "            path.append(candidates[idx])\n",
    "            dfs(idx+1, s+candidates[idx])\n",
    "            path.pop(-1)\n",
    "            dfs(idx+1, s)\n",
    "        res = set()\n",
    "        path = []\n",
    "        l = len(candidates)\n",
    "        candidates = sorted(candidates)\n",
    "        dfs(0, 0)\n",
    "        return list(map(list, res))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "\n",
    "class Solution:\n",
    "  def fourSum(self, nums, target):\n",
    "    \"\"\"\n",
    "    :type nums: List[int]\n",
    "    :type target: int\n",
    "    :rtype: List[List[int]]\n",
    "    \"\"\"\n",
    "    twoSum = defaultdict( list )\n",
    "    for i in range( len( nums ) - 1 ):\n",
    "      for j in range( i + 1, len( nums ) ):\n",
    "        twoSum[ nums[i] + nums[j] ].append( (i, j) )\n",
    "\n",
    "    ans = set()\n",
    "    for abSum in twoSum:\n",
    "      cdSum = target - abSum\n",
    "      if cdSum not in twoSum:\n",
    "        continue\n",
    "\n",
    "      for a, b in twoSum[ abSum ]:\n",
    "        for c, d in twoSum[ cdSum ]:\n",
    "          if len( { a, b, c, d } ) == 4:\n",
    "            ans.add( tuple(sorted(( nums[a], nums[b], nums[c], nums[d] ))) )\n",
    "\n",
    "    return [ list(t) for t in ans ]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    \n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        nums.sort()\n",
    "        result = set()\n",
    "        sum_of_two = {}\n",
    "        len_of_nums = len(nums)\n",
    "        if len_of_nums<4:\n",
    "            return []\n",
    "        sum_ij_min = nums[0] + nums[1]\n",
    "        sum_ij_threshold = target - sum_ij_min\n",
    "        sum_of_two[sum_ij_min] = [[0,1]]\n",
    "        for i in range(len_of_nums):\n",
    "            for j in range(i+1,len_of_nums):\n",
    "                if i==0 and j==1:\n",
    "                    continue\n",
    "                sum_ij = nums[i]+nums[j]\n",
    "                if sum_ij > sum_ij_threshold:\n",
    "                    break\n",
    "                key_list = sum_of_two.keys()\n",
    "                if sum_ij not in key_list:\n",
    "                    sum_of_two[sum_ij] = [[i,j]]\n",
    "                else:\n",
    "                    sum_of_two[sum_ij].append([i,j])\n",
    "                if target-sum_ij in key_list:\n",
    "                    for xy in sum_of_two[target-sum_ij]:\n",
    "                        if i not in xy and j not in xy:\n",
    "                            result.add(tuple(sorted([nums[xy[0]],nums[xy[1]],nums[i],nums[j]])))\n",
    "        return list(result)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        if len(nums) < 4:\n",
    "            return []\n",
    "        \n",
    "        def twoSum(nums,x1,x2):\n",
    "            t = target-(x1+x2)\n",
    "            left_added = set()\n",
    "            l,r = 0,len(nums)-1\n",
    "            result = []\n",
    "            while r > l:\n",
    "                if nums[l]+nums[r] == t:\n",
    "                    if nums[l] not in left_added:\n",
    "                        left_added.add(nums[l])\n",
    "                        result.append([x1,x2,nums[l],nums[r]])\n",
    "                    l += 1\n",
    "                    r -= 1\n",
    "                elif nums[l]+nums[r] > t:\n",
    "                    r -= 1\n",
    "                else:\n",
    "                    l += 1\n",
    "            return result\n",
    "        \n",
    "        nums.sort()\n",
    "        x12_record = []\n",
    "        result = []\n",
    "        for i in range(len(nums)-3):\n",
    "            for j in range(i+1,len(nums)-2):\n",
    "                if [nums[i],nums[j]] not in x12_record:\n",
    "                    x12_record.append([nums[i],nums[j]])\n",
    "                    for fourple in twoSum(nums[j+1:],nums[i],nums[j]):\n",
    "                        result.append(fourple)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: 'List[int]', target: 'int') -> 'List[List[int]]':\n",
    "        res, dic = set(), {}\n",
    "        nums.sort()\n",
    "        length = len(nums)\n",
    "        \n",
    "        # 构建两数结果集\n",
    "        for i in range(length):\n",
    "            for j in range(i+1, length):\n",
    "                key = nums[i] + nums[j]\n",
    "                if key not in dic:\n",
    "                    dic[key] = [(i, j)]\n",
    "                else:\n",
    "                    dic[key].append((i, j))\n",
    "        \n",
    "        \n",
    "        for i in range(length):\n",
    "            for j in range(i+1, length-2):\n",
    "                index = target - nums[i] - nums[j]\n",
    "                if index in dic:\n",
    "                    for tmp in dic[index]:\n",
    "                        # 去除重复利用的情况\n",
    "                        if tmp[0] > j:\n",
    "                            # 对结果去重\n",
    "                            res.add((nums[i], nums[j], nums[tmp[0]], nums[tmp[1]]))\n",
    "        \n",
    "        return [list(i) for i in res]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        res = set()\n",
    "        dic = {}\n",
    "        for i in range(len(nums)):\n",
    "            for j in range(i+1,len(nums)):\n",
    "                if nums[i] + nums[j] not in dic:\n",
    "                    dic[nums[i]+nums[j]] = [(i,j)]\n",
    "                else:\n",
    "                    dic[nums[i]+nums[j]].append((i,j))\n",
    "        for p in range(len(nums)):\n",
    "            for q in range(p+1,len(nums)):\n",
    "                if target - nums[p] - nums[q] in dic:\n",
    "                    for each in dic[target-nums[p]-nums[q]]:\n",
    "                        i,j = each[0],each[1]\n",
    "                        if len({i,j,p,q}) == 4:\n",
    "                            temp = [nums[i],nums[j],nums[p],nums[q]]\n",
    "                            temp.sort()\n",
    "                            temp = tuple(temp)#元组可以被哈希，但是列表不可以\n",
    "                            # t1,t2,t3,t4 = temp\n",
    "                            # aa = (nums[t1],nums[t2],nums[t3],nums[t4])\n",
    "                            res.add(temp)\n",
    "        return [list(a) for a in res]\n",
    "                    \n",
    "                \n",
    "            \n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        nums.sort()\n",
    "        length = len(nums)\n",
    "\n",
    "        ij_dict = dict()\n",
    "        res_set = set()\n",
    "        for i in range(length - 1):\n",
    "            for j in range(i+1, length):\n",
    "\n",
    "                ij_sum = nums[i] + nums[j]\n",
    "                m = target - ij_sum\n",
    "                if m in ij_dict:\n",
    "                    for item in ij_dict[m]:\n",
    "                        if item[1] < i:\n",
    "                            res_set.add((nums[item[0]], nums[item[1]], nums[i], nums[j]))\n",
    "\n",
    "                if ij_sum not in ij_dict:\n",
    "                    ij_dict[ij_sum] = [(i, j)]\n",
    "                else:\n",
    "                    ij_dict[ij_sum].append((i, j))\n",
    "\n",
    "        return [[item[0], item[1], item[2], item[3]]for item in res_set]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        se,dic = set(),{}\n",
    "        nums.sort()\n",
    "        length = len(nums)\n",
    "        for i in range(length):\n",
    "            for j in range(i+1,length):\n",
    "                tt = nums[i] + nums[j]\n",
    "                if tt in dic.keys():\n",
    "                    dic[tt].append((i,j))\n",
    "                else:\n",
    "                    dic[tt] = [(i,j)]\n",
    "        for i in range(length):\n",
    "            for j in range(i+1,length-2):\n",
    "                tt = target - nums[i] - nums[j]\n",
    "                if tt in dic.keys():\n",
    "                    for p in dic[tt]:\n",
    "                        if p[0] > j:\n",
    "                            se.add((nums[i],nums[j],nums[p[0]],nums[p[1]]))\n",
    "        return [list(i) for i in se]\n",
    "                \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "class Solution:\n",
    "    def fourSum(self, nums, target):\n",
    "        \"\"\"\n",
    "        :type nums: List[int]\n",
    "        :type target: int\n",
    "        :rtype: List[List[int]]\n",
    "        \"\"\"\n",
    "        sum_dic = collections.defaultdict(list)\n",
    "        res_set = set()\n",
    "        for i in range(len(nums)-1):\n",
    "            for j in range(i+1, len(nums)):\n",
    "                sum_dic[nums[i]+nums[j]].append((i, j))\n",
    "        for key in sum_dic.keys():\n",
    "            left_key = target-key\n",
    "            if left_key in sum_dic.keys():\n",
    "                for (i, j) in sum_dic[key]:\n",
    "                    for (k, l) in sum_dic[left_key]:\n",
    "                        if i != k and i != l and j != k and j != l:\n",
    "                            res_set.add(tuple(sorted([nums[i], nums[j], nums[k], nums[l]])))\n",
    "        return list(res_set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        s = set()\n",
    "        for i in range(0, len(nums) - 3):\n",
    "            for j in range(i + 1, len(nums) - 2):\n",
    "                left = j + 1\n",
    "                right = len(nums) - 1\n",
    "                while left < right:\n",
    "                    if nums[i] + nums[j] + nums[left] + nums[right] < target:\n",
    "                        left += 1\n",
    "                    elif nums[i] + nums[j] + nums[left] + nums[right] > target:\n",
    "                        right -= 1\n",
    "                    else:\n",
    "                        s.add((tuple(sorted([nums[i], nums[j], nums[left], nums[right]]))))\n",
    "                        right -=1\n",
    "                        left += 1\n",
    "        return list(s)        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\"\"\"\n",
    "# Definition for a Node.\n",
    "class Node:\n",
    "    def __init__(self, val=None, next=None):\n",
    "        self.val = val\n",
    "        self.next = next\n",
    "\"\"\"\n",
    "\n",
    "class Solution:\n",
    "    def insert(self, head: 'Node', insertVal: int) -> 'Node':\n",
    "        if not head:\n",
    "            head = Node(val=insertVal)\n",
    "            head.next = head\n",
    "            return head\n",
    "        if not head.next:\n",
    "            head.next = Node(val=insertVal)\n",
    "            return head\n",
    "        cur = head\n",
    "        while True:\n",
    "            if (cur.val <= insertVal and insertVal<=cur.next.val) or (cur.val <= insertVal and cur.next.val < cur.val) or (cur.next.val >= insertVal and cur.next.val < cur.val) or cur.next == head:\n",
    "                tmp = cur.next\n",
    "                add = Node(val=insertVal)\n",
    "                cur.next = add\n",
    "                add.next = tmp\n",
    "                break\n",
    "            cur = cur.next\n",
    "        return head        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\"\"\"\n",
    "# Definition for a Node.\n",
    "class Node:\n",
    "    def __init__(self, val=None, next=None):\n",
    "        self.val = val\n",
    "        self.next = next\n",
    "\"\"\"\n",
    "\n",
    "class Solution:\n",
    "    def insert(self, head: 'Node', insertVal: int) -> 'Node':\n",
    "      if not head:\n",
    "        head = Node(insertVal)\n",
    "        head.next = head\n",
    "        return head\n",
    "\n",
    "      prev, pos = None, head\n",
    "      nodes_set = set()\n",
    "      flag = False\n",
    "      max_node, min_node, max_prev, min_prev = head, head, None, None\n",
    "      while True:\n",
    "        if max_node.val <= pos.val:\n",
    "          max_node = pos\n",
    "          max_prev = prev\n",
    "          min_node = pos.next\n",
    "          min_prev = pos\n",
    "\n",
    "        if prev and (prev.val <= insertVal and pos.val >= insertVal):\n",
    "          prev.next = Node(insertVal, pos)\n",
    "          flag = True\n",
    "          break\n",
    "\n",
    "        if pos in nodes_set:\n",
    "          break\n",
    "        nodes_set.add(pos)\n",
    "        prev, pos = pos, pos.next\n",
    "\n",
    "      if not flag:\n",
    "        if max_node.val == min_node.val:\n",
    "          head.next = Node(insertVal, head.next)\n",
    "        elif insertVal < min_node.val:\n",
    "          max_node.next = Node(insertVal, min_node)\n",
    "        elif insertVal > max_node.val:\n",
    "          max_node.next = Node(insertVal, max_node.next)\n",
    "\n",
    "      return head"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\"\"\"\n",
    "# Definition for a Node.\n",
    "class Node:\n",
    "    def __init__(self, val=None, next=None):\n",
    "        self.val = val\n",
    "        self.next = next\n",
    "\"\"\"\n",
    "\n",
    "class Solution:\n",
    "    def insert(self, head: 'Node', insertVal: int) -> 'Node':\n",
    "        if not head:\n",
    "            node = Node(insertVal)\n",
    "            node.next = node\n",
    "            return node\n",
    "        node=Node(insertVal)\n",
    "        now=head\n",
    "        hashset=set()\n",
    "        minnode=head\n",
    "        while now:\n",
    "            if now in hashset:\n",
    "                break\n",
    "            else:\n",
    "                hashset.add(now)\n",
    "                if now.val==insertVal:\n",
    "                    minnode=now\n",
    "                    break\n",
    "                elif now.val<insertVal:\n",
    "                    if minnode.val<insertVal:\n",
    "                        if now.val>=minnode.val:\n",
    "                            minnode=now\n",
    "                    else:\n",
    "                        minnode=now\n",
    "                    \n",
    "                else:\n",
    "                    if minnode.val>insertVal and now.val>=minnode.val:\n",
    "                        minnode=now\n",
    "            now=now.next\n",
    "        temp=minnode.next\n",
    "        minnode.next=node\n",
    "        node.next=temp\n",
    "        return head\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def findMinDifference(self, timePoints: List[str]) -> int:\n",
    "      if(len(timePoints) > 24 * 60): return 0\n",
    "      n1 = int(''.join(timePoints[0].split(\":\")))\n",
    "      n1 = (n1 // 100) * 60 + n1 % 100\n",
    "      number = SortedList([n1])\n",
    "      result = float('inf')\n",
    "      for i in range(1, len(timePoints)):\n",
    "          temp = int(''.join(timePoints[i].split(\":\")))\n",
    "          temp = (temp // 100) * 60 + temp % 100\n",
    "          index = number.bisect_right(temp)\n",
    "          \n",
    "          if index==0 or index==len(number)-1:\n",
    "              cur_result = abs(temp - number[index])\n",
    "              result = min(result, cur_result)       \n",
    "\n",
    "          if -1<index-1:\n",
    "            cur_result=abs(temp - number[index - 1])\n",
    "            result = min(result, cur_result)\n",
    "          if index+1<len(number):\n",
    "            cur_result=abs(temp - number[index])\n",
    "            result = min(result, cur_result)\n",
    "\n",
    "          result = min(result, cur_result)\n",
    "          number.add(temp)\n",
    "\n",
    "      result = min(result, abs(1440 - number[-1] + number[0]))\n",
    "\n",
    "      return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def findMinDifference(self, timePoints: List[str]) -> int:\n",
    "      n1 = int(''.join(timePoints[0].split(\":\")))\n",
    "      n1 = (n1 // 100) * 60 + n1 % 100\n",
    "      number = SortedList([n1])\n",
    "      result = float('inf')\n",
    "      for i in range(1, len(timePoints)):\n",
    "          temp = int(''.join(timePoints[i].split(\":\")))\n",
    "          temp = (temp // 100) * 60 + temp % 100\n",
    "          index = number.bisect_right(temp)\n",
    "          \n",
    "          if index==0 or index==len(number)-1:\n",
    "              cur_result = abs(temp - number[index])\n",
    "              result = min(result, cur_result)       \n",
    "\n",
    "          if -1<index-1:\n",
    "            cur_result=abs(temp - number[index - 1])\n",
    "            result = min(result, cur_result)\n",
    "          if index+1<len(number):\n",
    "            cur_result=abs(temp - number[index])\n",
    "            result = min(result, cur_result)\n",
    "\n",
    "          result = min(result, cur_result)\n",
    "          number.add(temp)\n",
    "\n",
    "      result = min(result, abs(1440 - number[-1] + number[0]))\n",
    "\n",
    "      return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class DLinkNode:\n",
    "    def __init__(self, hour, minute, prev=None, next=None):\n",
    "        self.hour = hour\n",
    "        self.minute = minute\n",
    "        self.prev = prev\n",
    "        self.next = next\n",
    "\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.ring_link_list = None\n",
    "        self.time_map = defaultdict()\n",
    "        for ii in range(24):\n",
    "            self.time_map[ii] = None\n",
    "        self.minDiff = 1440\n",
    "\n",
    "    def insertIn(self, node, node_before):\n",
    "        if self.ring_link_list:\n",
    "            node_next = node_before.next\n",
    "            node_before.next = node\n",
    "            node.prev = node_before\n",
    "            node.next = node_next\n",
    "            node_next.prev = node\n",
    "        else:\n",
    "            self.ring_link_list = node\n",
    "            node.next = node\n",
    "            node.prev = node\n",
    "\n",
    "    def findBefore(self, node):\n",
    "        # 环形链表中没有元素时跳出----------------\n",
    "        if not self.ring_link_list:\n",
    "            self.time_map[node.hour] = node\n",
    "            return None\n",
    "        # 对应时间表是否有元素--------------------\n",
    "        if self.time_map[node.hour]:\n",
    "            handle_node = self.time_map[node.hour]\n",
    "            if node.minute < handle_node.minute:\n",
    "                # 更新\n",
    "                self.time_map[node.hour] = node\n",
    "                return handle_node.prev\n",
    "            else:\n",
    "                last_node = None\n",
    "                while node.minute >= handle_node.minute:\n",
    "                    last_node = handle_node\n",
    "                    handle_node = handle_node.next\n",
    "                    # 回环跳出\n",
    "                    if last_node == handle_node:\n",
    "                        return last_node\n",
    "                    # 超出跳出\n",
    "                    if handle_node.hour!=node.hour:\n",
    "                        return last_node\n",
    "                return last_node\n",
    "        else:\n",
    "            hour = node.hour\n",
    "            # print(hour)\n",
    "            while not self.time_map[hour]:\n",
    "                hour -= 1\n",
    "                if hour < 0:\n",
    "                    hour += 24\n",
    "            hour_node = self.time_map[hour]\n",
    "            start_hour_node = hour_node\n",
    "            while hour_node.next.hour == hour:\n",
    "                if hour_node.next == start_hour_node:\n",
    "                    self.time_map[node.hour] = node\n",
    "                    return hour_node\n",
    "                hour_node = hour_node.next\n",
    "            self.time_map[node.hour] = node\n",
    "            return hour_node\n",
    "\n",
    "    def renewMinDiff(self, node):\n",
    "        if node:\n",
    "            next_node = node.next\n",
    "            if next_node.hour<node.hour:\n",
    "                hour_diff = next_node.hour+24-node.hour\n",
    "            else:\n",
    "                hour_diff = next_node.hour-node.hour\n",
    "            minute_diff = hour_diff * 60\n",
    "            minute_diff += next_node.minute-node.minute\n",
    "            if minute_diff<0:\n",
    "                minute_diff += 1440\n",
    "            self.minDiff = min(self.minDiff, minute_diff)\n",
    "\n",
    "    def findMinDifference(self, timePoints: List[str]) -> int:\n",
    "        # 2<=timePoints <=2*10**4\n",
    "        minDiff = 24*60\n",
    "        for each_time in timePoints:\n",
    "            str_hour, str_minute = each_time.split(\":\")\n",
    "            hour, minute = int(str_hour), int(str_minute)\n",
    "            add_node = DLinkNode(hour, minute)\n",
    "            before_node = self.findBefore(add_node)\n",
    "            # if before_node:\n",
    "            #     print(before_node.hour, before_node.minute)\n",
    "            # else:\n",
    "            #     print(before_node)\n",
    "            self.insertIn(add_node, before_node)\n",
    "        handle_node = self.ring_link_list\n",
    "        flag = True\n",
    "        # print(\"----------------------------------------------\")\n",
    "        while flag or handle_node is not self.ring_link_list:\n",
    "            if flag:\n",
    "                flag = False\n",
    "            self.renewMinDiff(handle_node)\n",
    "            # print(handle_node.hour, handle_node.minute)\n",
    "            handle_node = handle_node.next\n",
    "            # print(self.minDiff)\n",
    "        return self.minDiff\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # res = inf\n",
    "        # directions = {\n",
    "        #     \"^\": (-1, 0),\n",
    "        #     \"v\": (1, 0),\n",
    "        #     \"<\": (0, -1),\n",
    "        #     \">\": (0, 1),\n",
    "        # }\n",
    "        # queue = [[0, start[0],start[1]]]\n",
    "        # seen = set()\n",
    "        # while queue:\n",
    "        #     count, x, y = heappop(queue)\n",
    "        #     if [x, y] == end:\n",
    "        #         return count \n",
    "        #     seen.add((x, y))\n",
    "        #     for ch, d in directions.items():\n",
    "        #         new_x, new_y = x+d[0], y+d[1]\n",
    "        #         if 0 <= new_x < len(matrix) and 0 <= new_y < len(matrix[0]) \\\n",
    "        #             and (new_x, new_y) not in seen:\n",
    "        #             if ch == matrix[x][y]:\n",
    "        #                 heappush(queue, [count, new_x, new_y])\n",
    "        #             else:\n",
    "        #                 heappush(queue, [count+1, new_x, new_y])\n",
    "        # return 0\n",
    "\n",
    "        # ------------------------------\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        dist = [[inf] * n for _ in range(m)]\n",
    "        dist[start[0]][start[1]] = 0\n",
    "        q = collections.deque([[start[0], start[1], 0]])\n",
    "        v = {(1, 0): \"v\", (-1, 0): \"^\", (0, 1): \">\", (0, -1): \"<\"}\n",
    "        while q:\n",
    "            s = len(q)\n",
    "            for _ in range(s):\n",
    "                x, y, d = q.popleft()\n",
    "                for l, r in v.keys():\n",
    "                    newX = l + x\n",
    "                    newY = r + y\n",
    "                    if 0 <= newX < m and 0 <= newY < n:\n",
    "                        o = 0 if v[(l, r)] == matrix[x][y] else 1\n",
    "                        if dist[newX][newY] > o + d:\n",
    "                            dist[newX][newY] = o + d\n",
    "                            if o == 0:\n",
    "                                q.appendleft([newX, newY, d])\n",
    "                            else:\n",
    "                                q.append([newX, newY, o + d])\n",
    "        return dist[end[0]][end[1]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        \n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if (x,y) in vis:\n",
    "                continue\n",
    "            vis.add((x,y))\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        # vis.add((xx,yy,cc))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        \n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if (x,y) in vis:\n",
    "                continue\n",
    "            vis.add((x,y))\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        # vis.add((xx,yy,cc))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        options = {'>':lambda x,y :(x,y+1),'<':lambda x,y:(x,y-1),'^':lambda x,y:(x-1,y),'v':lambda x,y:(x+1,y)}\n",
    "        m,n = len(matrix),len(matrix[0])\n",
    "        queue = []\n",
    "        x,y = start\n",
    "        queue.append([0,x,y])\n",
    "        visited = set()\n",
    "        while queue:\n",
    "            count,x,y = heappop(queue)\n",
    "            if [x,y] == end:\n",
    "                return count\n",
    "            if (x,y) in visited:\n",
    "                continue\n",
    "            visited.add((x,y))\n",
    "            newX,newY = options[matrix[x][y]](x,y)\n",
    "            if 0<=newX<m and 0<=newY<n and (newX,newY) not in visited:\n",
    "                heappush(queue,[count,newX,newY])\n",
    "            for i,j in [[x,y+1],[x,y-1],[x+1,y],[x-1,y]]:\n",
    "                if not(0<=i<m and 0<=j<n) or (i,j) in visited or [i,j] == [newX,newY]:\n",
    "                    continue\n",
    "                heappush(queue,[count+1,i,j])\n",
    "        return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "DIRS = {\"^\":(-1, 0), \"v\":(1, 0), \"<\":(0, -1), \">\":(0, 1)}\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 基本参数\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        i, j = start\n",
    "        # 准备工作，一个地图，一个集合，一个堆\n",
    "        dist = [[inf] * n for _ in range(m)]\n",
    "        dist[i][j] = 0\n",
    "        seen = set()\n",
    "        h = [(0, i, j)]\n",
    "        # 开始走起来\n",
    "        while h:\n",
    "            d, i, j = heappop(h)\n",
    "            if [i, j] == end: return d\n",
    "            if (i, j) in seen: continue\n",
    "            seen.add((i, j))\n",
    "            for x, y in ((i + 1, j), (i - 1, j), (i, j + 1), (i, j - 1)):\n",
    "                if m > x >= 0 <= y < n:\n",
    "                    nd = d + int((x - i, y - j) != DIRS[matrix[i][j]])\n",
    "                    if nd < dist[x][y]:\n",
    "                        dist[x][y] = nd\n",
    "                        heappush(h, (nd, x, y))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        r, c = len(matrix), len(matrix[0])\n",
    "\n",
    "        queue = collections.deque([(start[0], start[1], 0)])\n",
    "        seen = set()\n",
    "\n",
    "        mp = {\n",
    "            '^':(-1,0),\n",
    "            'v':(1, 0),\n",
    "            '<':(0, -1),\n",
    "            '>':(0, 1)\n",
    "        }\n",
    "\n",
    "        while queue:\n",
    "            i, j, step = queue.popleft()\n",
    "            if i == end[0] and j == end[1]:\n",
    "                return step\n",
    "\n",
    "            if (i,j) in seen:\n",
    "                continue\n",
    "            \n",
    "            seen.add((i, j))\n",
    "\n",
    "            for di, dj in [(1, 0), (-1, 0), (0, 1), (0, -1)]:\n",
    "                newi, newj = i + di, j + dj\n",
    "                if 0 <= newi < r and 0 <= newj < c:\n",
    "                    if mp[matrix[i][j]] == (di, dj):\n",
    "                        queue.appendleft((newi, newj, step))\n",
    "                    else:\n",
    "                        queue.append((newi, newj, step + 1))\n",
    "\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        #迪杰斯特拉，用操作次数作为时间\n",
    "        m = len(matrix)\n",
    "        n = len(matrix[0])\n",
    "        direct = [(1, 0), (-1, 0), (0, -1), (0, 1)]\n",
    "        import heapq\n",
    "        vst = set()\n",
    "        q = []\n",
    "        heapq.heappush(q, (0, (start[0], start[1])))\n",
    "        end = (end[0], end[1])\n",
    "\n",
    "        while q:\n",
    "            opera, u = heapq.heappop(q)\n",
    "            print(u)\n",
    "            if u[0] == end[0] and u[1] == end[1]:\n",
    "                return opera\n",
    "            if u in vst:\n",
    "                continue\n",
    "            vst.add((u[0], u[1]))\n",
    "            for dx, dy in direct:\n",
    "                nx = u[0] + dx\n",
    "                ny = u[1] + dy\n",
    "                if 0<= nx < m and 0<= ny < n:\n",
    "                    if matrix[u[0]][u[1]] == \"^\":\n",
    "                        if dx == -1 and dy == 0:\n",
    "                            heapq.heappush(q, (opera, (nx, ny)))\n",
    "                        else:\n",
    "                            heapq.heappush(q, (opera+1, (nx, ny)))\n",
    "\n",
    "                    if matrix[u[0]][u[1]] == \"v\":\n",
    "                        if dx == 1 and dy == 0:\n",
    "                            heapq.heappush(q, (opera, (nx, ny)))\n",
    "                        else:\n",
    "                            heapq.heappush(q, (opera+1, (nx, ny)))\n",
    "                    \n",
    "                    if matrix[u[0]][u[1]] == \"<\":\n",
    "                        if dx == 0 and dy == -1:\n",
    "                            heapq.heappush(q, (opera, (nx, ny)))\n",
    "                        else:\n",
    "                            heapq.heappush(q, (opera+1, (nx, ny)))\n",
    "\n",
    "                    if matrix[u[0]][u[1]] == \">\":\n",
    "                        if dx == 0 and dy == 1:\n",
    "                            heapq.heappush(q, (opera, (nx, ny)))\n",
    "                        else:\n",
    "                            heapq.heappush(q, (opera+1, (nx, ny)))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import deque\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        r,c = len(matrix),len(matrix[0])\n",
    "        dist = [float('inf')]*(r*c)\n",
    "        sx,sy = start[0],start[1]\n",
    "        dist[sx*c+sy] = 0\n",
    "        dx = [-1,1,0,0]\n",
    "        dy = [0,0,-1,1]\n",
    "        letter_to_num = {'^':0,'v':1,'<':2,'>':3}\n",
    "        ex,ey=end[0],end[1]\n",
    "        visited = set()\n",
    "        queue = deque([(sx,sy)])\n",
    "        while queue:\n",
    "            x,y=queue.popleft()\n",
    "            if (x,y) in visited:\n",
    "                continue\n",
    "            visited.add((x,y))\n",
    "            cur_pos = x*c +y\n",
    "            for i in range(4):\n",
    "                nx,ny = x+dx[i], y+dy[i]\n",
    "                n_pos = nx*c + ny\n",
    "                new_dist = dist[cur_pos] + (0 if letter_to_num[matrix[x][y]]==i else 1)\n",
    "                if 0<=nx<r and 0<=ny<c and new_dist<dist[n_pos]:\n",
    "                    dist[n_pos] = new_dist\n",
    "                    if letter_to_num[matrix[x][y]] == i:\n",
    "                        queue.appendleft((nx,ny))\n",
    "                    else:\n",
    "                        queue.append((nx, ny))\n",
    "            pass\n",
    "        \n",
    "        return dist[ex*c+ey]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        m = {\n",
    "            \"v\": 0,\n",
    "            \"^\": 1,\n",
    "            \">\": 2,\n",
    "            \"<\": 3,\n",
    "        }\n",
    "        vis = {(start[0], start[1]): 0}\n",
    "        best = set()\n",
    "        deq = deque([(0, start[0], start[1])])\n",
    "\n",
    "        while deq:\n",
    "            wei, i, j = deq.popleft()\n",
    "            if (i, j) in best:\n",
    "                continue\n",
    "            best.add((i, j))\n",
    "            for p, pos in enumerate(((i+1, j), (i-1, j), (i, j+1), (i, j-1))):\n",
    "                x, y = pos\n",
    "                if 0 <= x < len(matrix) and 0 <= y < len(matrix[0]):\n",
    "                    w = wei + 1\n",
    "                    if p == m[matrix[i][j]]:\n",
    "                        w -= 1\n",
    "                    if (not (x, y) in vis) or ((x, y) not in best and w < vis[(x, y)]):\n",
    "                        vis[(x, y)] = w\n",
    "                        if w == wei:\n",
    "                            deq.appendleft((w, x, y))\n",
    "                        else:\n",
    "                            deq.append((w, x, y))\n",
    "        return vis[(end[0], end[1])]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        visited = set()\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "        ans = 0\n",
    "        que = []\n",
    "        \n",
    "        def dfs(cur):\n",
    "            if cur in visited:\n",
    "                return\n",
    "            else:\n",
    "                visited.add(cur)\n",
    "                nxt = None\n",
    "                match matrix[cur[0]][cur[1]]:\n",
    "                    case \"^\":\n",
    "                        nxt = (cur[0]-1, cur[1])\n",
    "                    case \"v\":\n",
    "                        nxt = (cur[0]+1, cur[1])\n",
    "                    case \"<\":\n",
    "                        nxt = (cur[0], cur[1]-1)\n",
    "                    case \">\":\n",
    "                        nxt = (cur[0], cur[1]+1)\n",
    "                for nx, ny in [[cur[0]-1, cur[1]], [cur[0]+1, cur[1]], [cur[0], cur[1]-1], [cur[0], cur[1]+1]]:\n",
    "                    if 0 <= nx < m and 0 <= ny < n:\n",
    "                        if (nx, ny) == nxt:\n",
    "                            dfs(nxt)\n",
    "                        else:\n",
    "                            que.append((nx, ny))\n",
    "            \n",
    "        temp = [tuple(start)]\n",
    "        end = tuple(end)\n",
    "        while temp:\n",
    "            for _ in range(len(temp)):\n",
    "                dfs(temp.pop())\n",
    "            if end in visited:\n",
    "                return ans\n",
    "            ans += 1\n",
    "            temp = que[:]\n",
    "            que = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        res = inf\n",
    "        directions = {\n",
    "            \"^\": (-1, 0),\n",
    "            \"v\": (1, 0),\n",
    "            \"<\": (0, -1),\n",
    "            \">\": (0, 1),\n",
    "        }\n",
    "        queue = [[0, start[0],start[1]]]\n",
    "        seen = set()\n",
    "        while queue:\n",
    "            count, x, y = heappop(queue)\n",
    "            if [x, y] == end:\n",
    "                return count \n",
    "            seen.add((x, y))\n",
    "            for ch, d in directions.items():\n",
    "                new_x, new_y = x+d[0], y+d[1]\n",
    "                if 0 <= new_x < len(matrix) and 0 <= new_y < len(matrix[0]) \\\n",
    "                    and (new_x, new_y) not in seen:\n",
    "                    if ch == matrix[x][y]:\n",
    "                        heappush(queue, [count, new_x, new_y])\n",
    "                    else:\n",
    "                        heappush(queue, [count+1, new_x, new_y])\n",
    "        return 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import *\n",
    "from heapq import *\n",
    "from sys import *\n",
    "from math import *\n",
    "from itertools import *\n",
    "from functools import *\n",
    "from string import *\n",
    "from bisect import *\n",
    "from graphlib import *\n",
    "from sortedcontainers import *\n",
    "from copy import *\n",
    "\n",
    "class Dijkstra:\n",
    "    def __init__(self, edges=[], undirected=True):\n",
    "        self.g = defaultdict(list)\n",
    "        self.undirected = undirected\n",
    "        for x, y, w in edges: self.add_edge(x, y, w)\n",
    "    def get_min_dist(self, src=0):\n",
    "        dist = defaultdict(lambda:inf)\n",
    "        dist[src] = 0\n",
    "        sl = [(dist[src], src)]\n",
    "        while sl:\n",
    "            d, x = heappop(sl)\n",
    "            for y, cost in self.g[x]:\n",
    "                if dist[x] + cost < dist[y]:\n",
    "                    dist[y] = dist[x] + cost\n",
    "                    heappush(sl, (dist[y], y))\n",
    "        return dist\n",
    "    def add_edge(self, x, y, w):\n",
    "        self.g[x].append((y, w))\n",
    "        if self.undirected: self.g[y].append((x, w))\n",
    "        \n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        dct = dict(zip([(-1, 0), (1, 0), (0, -1), (0, 1)], [\"^\",\"v\",\"<\",\">\"]))\n",
    "        m, n = len(matrix), len(matrix[0])\n",
    "\n",
    "        dijkstra = Dijkstra(edges=[], undirected=False)\n",
    "        # dijkstra.add_edge(x, y, w)\n",
    "\n",
    "        for x in range(m):\n",
    "            for y in range(n):\n",
    "                for dx, dy in (0, 1), (1, 0), (-1, 0), (0, -1):\n",
    "                    nx, ny = x + dx, y + dy\n",
    "                    if 0 <= nx < m and 0 <= ny < n:\n",
    "                        dijkstra.add_edge((x, y), (nx, ny), int(dct[(dx, dy)] != matrix[x][y]))\n",
    "        src, dst = tuple(start), tuple(end)\n",
    "        min_dist = dijkstra.get_min_dist(src=src)[dst]  \n",
    "        return min_dist\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt_hq(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        \n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if (x,y) in vis:\n",
    "                continue\n",
    "            vis.add((x,y))\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        # vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    def conveyorBelt_my1(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        vis.add((start[0],start[1],0))\n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy,cc) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100 my_bfs\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q=deque() # q = [] \n",
    "        q.appendleft((start[0],start[1],0)) # heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        vis.add((start[0],start[1],0))\n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            x,y,c = q.pop()  # ,y,c = q.pop()  # c, x,y = heappop(q)\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                res=min(res,c)\n",
    "                # return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy,cc) not in vis and cc<=maxc:\n",
    "                        q.appendleft((xx,yy,cc)) # heappush(q, (cc,xx,yy)) \n",
    "                        vis.add((xx,yy,cc))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 图问题\n",
    "        m, n = len(matrix), len(matrix[0])  # 矩形的长宽\n",
    "        max_cost = abs(start[0]-end[0]) + abs(start[1]-end[1]) # 最大开销是每个地方都施法一次，直接走横线和竖线\n",
    "        q = deque()\n",
    "        q.appendleft((start[0], start[1], 0))  # 保存状态(x, y, cost)，表示从起点到x, y的目前最小花费为cost\n",
    "        visited = set()\n",
    "        visited.add((start[0], start[1], 0))\n",
    "        state_map = {'^': (-1, 0), 'v': (1, 0), '<': (0, -1), '>': (0, 1)}\n",
    "        results = max_cost\n",
    "        while q:\n",
    "            x, y, cost = q.pop()\n",
    "            # if (x, y) in visited:  # 如果返回的话，一定是非最小值，所以直接放弃\n",
    "            #     continue\n",
    "            # visited.add((x, y, cost))\n",
    "            if [x, y] == end:\n",
    "                # print((x, y, cost))\n",
    "                results = min(results, cost)\n",
    "                # return cost\n",
    "            for (dx, dy) in [(1,0),(-1,0),(0,1),(0,-1)]:\n",
    "                xx, yy = x+dx, y+dy\n",
    "                if 0 <= xx < m and 0 <= yy < n:\n",
    "                    if state_map[matrix[x][y]] == (dx, dy):\n",
    "                        cc = cost\n",
    "                    else:\n",
    "                        cc = cost + 1  # 如果能到则不用改，否则cost+1说明要改\n",
    "                    if (xx, yy, cc) not in visited and cc <= max_cost:  # 要保证这个值小于最大值才有意义，不过我觉得到不必\n",
    "                        q.appendleft((xx, yy, cc))\n",
    "                        visited.add((xx, yy, cc))\n",
    "        return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt_hq(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        \n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if (x,y) in vis:\n",
    "                continue\n",
    "            vis.add((x,y))\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        # vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    def conveyorBelt_my1(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        vis.add((start[0],start[1],0))\n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy,cc) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100 my_bfs\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q=deque() # q = [] \n",
    "        q.appendleft((start[0],start[1],0)) # heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        vis.add((start[0],start[1],0))\n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            x,y,c = q.pop()  # ,y,c = q.pop()  # c, x,y = heappop(q)\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                res=min(res,c)\n",
    "                # return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy,cc) not in vis and cc<=maxc:\n",
    "                        q.appendleft((xx,yy,cc)) # heappush(q, (cc,xx,yy)) \n",
    "                        vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def conveyorBelt_hq(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        \n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if (x,y) in vis:\n",
    "                continue\n",
    "            vis.add((x,y))\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        # vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    def conveyorBelt_my1(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q = [] # q=deque()\n",
    "        heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        vis.add((start[0],start[1],0))\n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            c, x,y = heappop(q)  # q.pop()\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                # res=min(res,c)\n",
    "                return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy,cc) not in vis and cc<=maxc:\n",
    "                        heappush(q, (cc,xx,yy))  # q.appendleft((xx,yy,cc))\n",
    "                        vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    def conveyorBelt(self, matrix: List[str], start: List[int], end: List[int]) -> int:\n",
    "        # 100*100 my_bfs\n",
    "        # 从start花费cost到达[i,j],记为(i,j,c) , 最大 maxc\n",
    "        m,n=len(matrix),len(matrix[0])\n",
    "        maxc = abs(start[0]-end[0])+abs(start[1]-end[1])\n",
    "        q=deque() # q = [] \n",
    "        q.appendleft((start[0],start[1],0)) # heappush(q,(0, start[0],start[1]))  # q.appendleft((start[0],start[1],0))\n",
    "        vis=set()\n",
    "        vis.add((start[0],start[1],0))\n",
    "        d={'^':(-1,0),'v':(1,0),'<':(0,-1),'>':(0,1)}\n",
    "        res=maxc\n",
    "        while q:\n",
    "            x,y,c = q.pop()  # ,y,c = q.pop()  # c, x,y = heappop(q)\n",
    "            if [x,y]==end:\n",
    "                # print((x,y,c))\n",
    "                res=min(res,c)\n",
    "                # return c\n",
    "            di = [(1,0),(-1,0),(0,1),(0,-1)]\n",
    "            for dx,dy in di:\n",
    "                xx,yy=x+dx,y+dy\n",
    "                if m>xx>=0<=yy<n:\n",
    "                    if d[matrix[x][y]]==(dx,dy):\n",
    "                        cc=c\n",
    "                    else:\n",
    "                        cc=c+1\n",
    "                    if (xx,yy,cc) not in vis and cc<=maxc:\n",
    "                        q.appendleft((xx,yy,cc)) # heappush(q, (cc,xx,yy)) \n",
    "                        vis.add((xx,yy,cc))\n",
    "        return res\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Node:\n",
    "    def __init__(self, val, parent = None):\n",
    "        self.val = val\n",
    "        self.parent = parent\n",
    "\n",
    "class Solution:\n",
    "    def add(self, val):\n",
    "\n",
    "        self.nodes[val] = Node(val)\n",
    "\n",
    "        return\n",
    "\n",
    "    def findRoot(self, node):\n",
    "        if not node.parent:\n",
    "            return node\n",
    "\n",
    "        root = node\n",
    "        while root.parent:\n",
    "            root = root.parent\n",
    "\n",
    "        while node != root:\n",
    "            tmp = node.parent\n",
    "            node.parent = root\n",
    "            node = tmp\n",
    "\n",
    "        return root\n",
    "\n",
    "    def merge(self, A, B, remove_list):\n",
    "        root_A = self.findRoot(A)\n",
    "        root_B = self.findRoot(B)\n",
    "\n",
    "        if root_A == root_B:\n",
    "            remove_list.append([A.val, B.val])\n",
    "            return \n",
    "\n",
    "        root_A.parent = root_B\n",
    "        \n",
    "\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        self.nodes = dict()\n",
    "        \n",
    "        res = []\n",
    "        for val_A, val_B in edges:\n",
    "            if val_A not in self.nodes:\n",
    "                self.add(val_A)\n",
    "            \n",
    "            if val_B not in self.nodes:\n",
    "                self.add(val_B)\n",
    "\n",
    "            A = self.nodes[val_A]\n",
    "            B = self.nodes[val_B]\n",
    "            self.merge(A, B, res)\n",
    "\n",
    "        return res[-1] if res else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        n = len(edges)\n",
    "        graph = defaultdict(set)\n",
    "        degrees = [0] * (n+1)\n",
    "        for a,b in edges:\n",
    "            graph[a].add(b)\n",
    "            graph[b].add(a)\n",
    "            degrees[a] += 1\n",
    "            degrees[b] += 1\n",
    "        \n",
    "        q = deque([i for i in range(1,n+1) if degrees[i] == 1])\n",
    "        seen = set()\n",
    "        while q:\n",
    "            cur = q.popleft()\n",
    "            seen.add(cur)\n",
    "            for j in graph[cur]:\n",
    "                graph[j].remove(cur)\n",
    "                degrees[j] -= 1\n",
    "                if degrees[j] == 1:\n",
    "                    q.append(j)\n",
    "        \n",
    "        for i in range(n-1,-1,-1):\n",
    "            a,b = edges[i]\n",
    "            if a not in seen and b not in seen:\n",
    "                return edges[i]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Node:\n",
    "    def __init__(self, val, parent = None):\n",
    "        self.val = val\n",
    "        self.parent = parent\n",
    "\n",
    "class Solution:\n",
    "    def add(self, val):\n",
    "\n",
    "        self.nodes[val] = Node(val)\n",
    "\n",
    "        return\n",
    "\n",
    "    def findRoot(self, node):\n",
    "        if not node.parent:\n",
    "            return node\n",
    "\n",
    "        root = node\n",
    "        while root.parent:\n",
    "            root = root.parent\n",
    "\n",
    "        while node != root:\n",
    "            tmp = node.parent\n",
    "            node.parent = root\n",
    "            node = tmp\n",
    "\n",
    "        return root\n",
    "\n",
    "    def merge(self, A, B, remove_list):\n",
    "        root_A = self.findRoot(A)\n",
    "        root_B = self.findRoot(B)\n",
    "\n",
    "        if root_A == root_B:\n",
    "            remove_list.append([A.val, B.val])\n",
    "            return \n",
    "\n",
    "        root_A.parent = root_B\n",
    "        \n",
    "\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        self.nodes = dict()\n",
    "        \n",
    "        res = []\n",
    "        for val_A, val_B in edges:\n",
    "            if val_A not in self.nodes:\n",
    "                self.add(val_A)\n",
    "            \n",
    "            if val_B not in self.nodes:\n",
    "                self.add(val_B)\n",
    "\n",
    "            A = self.nodes[val_A]\n",
    "            B = self.nodes[val_B]\n",
    "            self.merge(A, B, res)\n",
    "\n",
    "        return res[-1] if res else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class UF:\n",
    "    def __init__(self):\n",
    "        self.parent = {}\n",
    "        self.size = {}\n",
    "        self.cnt = 0\n",
    "    def add(self, x):\n",
    "        self.parent[x] = x\n",
    "        self.size[x] = 1\n",
    "        self.cnt += 1\n",
    "    \n",
    "    def find(self, x):\n",
    "        if self.parent[x] != x:\n",
    "            self.parent[x] = self.find(self.parent[x])\n",
    "        \n",
    "        return self.parent[x]\n",
    "    \n",
    "    def connect(self, p, q):\n",
    "        return self.find(p) == self.find(q)\n",
    "    \n",
    "    def union(self, p, q):\n",
    "        if self.connect(p, q): return \n",
    "\n",
    "        leader_p, leader_q = self.find(p), self.find(q)\n",
    "        \n",
    "        if self.size[leader_p] < self.size[leader_q]:\n",
    "            self.parent[leader_p] = leader_q\n",
    "            self.size[leader_q] += self.size[leader_p]\n",
    "            del self.size[leader_p]\n",
    "        else:\n",
    "            self.parent[leader_q] = leader_p\n",
    "            self.size[leader_p] += self.size[leader_q]\n",
    "            del self.size[leader_q]\n",
    "        \n",
    "        self.cnt -= 1\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        n = len(edges)\n",
    "        uf = UF()\n",
    "        for i in range(1, n+1): \n",
    "            uf.add(i)\n",
    "\n",
    "        for edge in edges:\n",
    "            a, b = edge\n",
    "            if uf.connect(a, b): \n",
    "                return [a, b]\n",
    "            else:\n",
    "                uf.union(a, b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        class union_finder:\n",
    "            def __init__(self, n) -> None:\n",
    "                self.root = [i for i in range(n)]\n",
    "                self.rank = [0 for i in range(n)]\n",
    "\n",
    "            def find(self, x):\n",
    "                if x == self.root[x]:\n",
    "                    return x\n",
    "                rootX = self.find(self.root[x])\n",
    "                self.root[x] = rootX\n",
    "                return rootX\n",
    "\n",
    "            def is_connect(self, x, y):\n",
    "                rootX = self.find(x)\n",
    "                rootY = self.find(y)\n",
    "                return rootX == rootY\n",
    "\n",
    "            def union(self, x, y):\n",
    "                rootX = self.find(x)\n",
    "                rootY = self.find(y)\n",
    "                if self.rank[rootX] > self.rank[rootY]:\n",
    "                    self.root[rootY] = rootX\n",
    "                elif self.rank[rootY] > self.rank[rootX]:\n",
    "                    self.root[rootX] = rootY\n",
    "                else:\n",
    "                    self.rank[rootX] += 1\n",
    "                    self.root[rootY] = rootX\n",
    "        n = len(edges)\n",
    "        finder = union_finder(n)\n",
    "        \n",
    "        vis = set()\n",
    "        for i, edge in enumerate(edges):\n",
    "            x, y = edge\n",
    "            x -= 1\n",
    "            y -= 1\n",
    "            if not finder.is_connect(x, y):\n",
    "                finder.union(x, y)\n",
    "                vis.add(i)\n",
    "        \n",
    "        return edges[list(set(range(n)) - vis)[0]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class UF:\n",
    "    def __init__(self):\n",
    "        self.parent = {}\n",
    "        self.size = {}\n",
    "        self.cnt = 0\n",
    "    def add(self, x):\n",
    "        self.parent[x] = x\n",
    "        self.size[x] = 1\n",
    "        self.cnt += 1\n",
    "    \n",
    "    def find(self, x):\n",
    "        if self.parent[x] != x:\n",
    "            self.parent[x] = self.find(self.parent[x])\n",
    "        \n",
    "        return self.parent[x]\n",
    "    \n",
    "    def connect(self, p, q):\n",
    "        return self.find(p) == self.find(q)\n",
    "    \n",
    "    def union(self, p, q):\n",
    "        if self.connect(p, q): return \n",
    "\n",
    "        leader_p, leader_q = self.find(p), self.find(q)\n",
    "        \n",
    "        if self.size[leader_p] < self.size[leader_q]:\n",
    "            self.parent[leader_p] = leader_q\n",
    "            self.size[leader_q] += self.size[leader_p]\n",
    "            del self.size[leader_p]\n",
    "        else:\n",
    "            self.parent[leader_q] = leader_p\n",
    "            self.size[leader_p] += self.size[leader_q]\n",
    "            del self.size[leader_q]\n",
    "        \n",
    "        self.cnt -= 1\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        uf = UF()\n",
    "        n = len(edges)\n",
    "        for i in range(1, n+1):\n",
    "            uf.add(i)\n",
    "        \n",
    "        for edge in edges:\n",
    "            a, b = edge\n",
    "            if uf.connect(a, b):\n",
    "                return [a, b]\n",
    "            uf.union(a, b)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Node:\n",
    "    def __init__(self, val, parent = None):\n",
    "        self.val = val\n",
    "        self.parent = parent\n",
    "\n",
    "class Solution:\n",
    "    def add(self, val):\n",
    "\n",
    "        self.nodes[val] = Node(val)\n",
    "\n",
    "        return\n",
    "\n",
    "    def findRoot(self, node):\n",
    "        if not node.parent:\n",
    "            return node\n",
    "\n",
    "        root = node\n",
    "        while root.parent:\n",
    "            root = root.parent\n",
    "\n",
    "        while node != root:\n",
    "            tmp = node.parent\n",
    "            node.parent = root\n",
    "            node = tmp\n",
    "\n",
    "        return root\n",
    "\n",
    "    def merge(self, A, B, remove_list):\n",
    "        root_A = self.findRoot(A)\n",
    "        root_B = self.findRoot(B)\n",
    "\n",
    "        if root_A == root_B:\n",
    "            remove_list.append([A.val, B.val])\n",
    "            return \n",
    "\n",
    "        root_A.parent = root_B\n",
    "        \n",
    "\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        self.nodes = dict()\n",
    "        \n",
    "        res = []\n",
    "        for val_A, val_B in edges:\n",
    "            if val_A not in self.nodes:\n",
    "                self.add(val_A)\n",
    "            \n",
    "            if val_B not in self.nodes:\n",
    "                self.add(val_B)\n",
    "\n",
    "            A = self.nodes[val_A]\n",
    "            B = self.nodes[val_B]\n",
    "            self.merge(A, B, res)\n",
    "\n",
    "        return res[-1] if res else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findRedundantConnection(self, edges: List[List[int]]) -> List[int]:\n",
    "        n = len(edges)\n",
    "        Hashtable = defaultdict(lambda :set())\n",
    "        Hashtable[0].clear()\n",
    "        Hashtable[1].clear()\n",
    "\n",
    "        for i in range(n):\n",
    "            inflag0 , inflag1 = False ,False\n",
    "            inflagi0, inflagi1 = -1, -1\n",
    "            for key , val in Hashtable.items():\n",
    "                if edges[i][0] in val:\n",
    "                    inflag0 = True\n",
    "                    inflagi0 = key\n",
    "                if edges[i][1] in val:\n",
    "                    inflag1 = True\n",
    "                    inflagi1 = key\n",
    "                if inflag0 and inflag1:\n",
    "                    break\n",
    "\n",
    "            if not inflag0 and not inflag1:\n",
    "                for k in range(n):\n",
    "                    if Hashtable[k] == set():\n",
    "                        Hashtable[k].add(edges[i][0])\n",
    "                        Hashtable[k].add(edges[i][1])\n",
    "                        break\n",
    "            elif inflag0 and inflag1:\n",
    "                if inflagi0 == inflagi1:\n",
    "                    return edges[i]\n",
    "                else:\n",
    "                    Hashtable[inflagi0] = Hashtable[inflagi0] | Hashtable[inflagi1]\n",
    "                    Hashtable[inflagi1].clear()\n",
    "            else:\n",
    "                if inflag0:\n",
    "                    Hashtable[inflagi0].add(edges[i][1])\n",
    "                else:\n",
    "                    Hashtable[inflagi1].add(edges[i][0])\n",
    "            # print(Hashtable.items())\n",
    "        return []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        def backtrack(seen, path):\n",
    "            if len(path) == len(nums):\n",
    "                if ''.join(path) not in path_set:\n",
    "                    path_set.add(''.join(path))\n",
    "                    ans.append([int(x) for x in path])\n",
    "                return\n",
    "            \n",
    "            for i in range(len(nums)):\n",
    "                if not seen[i]:\n",
    "                    seen[i] = True\n",
    "                    path.append(str(nums[i]))\n",
    "                    backtrack(seen, path)\n",
    "                    seen[i] = False\n",
    "                    path.pop()\n",
    "\n",
    "        ans = []\n",
    "        path_set = set()\n",
    "        backtrack([False]*len(nums), [])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        nums.sort()\n",
    "        flag = set()\n",
    "        result = []\n",
    "        path = []\n",
    "        n = len(nums)\n",
    "        def backtrack(array,n):\n",
    "            if len(path) == n:\n",
    "                tp = tuple(path)\n",
    "                if tp not in flag:\n",
    "                    result.append(path[:])\n",
    "                    flag.add(tuple(path))\n",
    "                return\n",
    "            for idx,val in enumerate(array):\n",
    "                path.append(val)\n",
    "                del array[idx]\n",
    "                backtrack(array, n)\n",
    "                array.insert(idx,val)\n",
    "                path.pop()\n",
    "        backtrack(nums, n)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        ans=[]\n",
    "        has=set()\n",
    "        nums.sort()\n",
    "        def go(ind):\n",
    "            if ind==len(nums):\n",
    "                k=tuple(nums)\n",
    "                if k in has:\n",
    "                    return\n",
    "                has.add(k)\n",
    "                \n",
    "                ans.append(nums[:])\n",
    "                return\n",
    "            for i in range(ind,len(nums)):\n",
    "                nums[i],nums[ind]=nums[ind],nums[i]\n",
    "                go(ind+1)\n",
    "                nums[i],nums[ind]=nums[ind],nums[i]\n",
    "        go(0)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        '''原来第一次做出来的'''\n",
    "        # def dfs(q):\n",
    "        #     if len(q) == len(nums) and tuple(q) not in st:\n",
    "        #         st.add(tuple(q))\n",
    "        #         res.append(q[:])\n",
    "        #         return # ！要return\n",
    "        #     for i in range(len(nums)):\n",
    "        #         if vis[i] == 0:\n",
    "        #             vis[i] = 1\n",
    "        #             q.append(nums[i])\n",
    "        #             dfs(q)\n",
    "        #             q.pop()\n",
    "        #             vis[i] = 0\n",
    "        \n",
    "        # res = []\n",
    "        # st = set()\n",
    "        # vis = [0 for _ in range(len(nums))]\n",
    "        # dfs([])\n",
    "        # return res\n",
    "        '''第二遍第一次尝试，没做出来'''\n",
    "        def dfs(q):\n",
    "            if len(q) == len(nums) and tuple(q) not in st:\n",
    "            #if len(q) == len(nums):\n",
    "                res.append(q[:])\n",
    "                st.add(tuple(q[:]))\n",
    "                return\n",
    "            \n",
    "            #for i in range(pos, len(nums)):\n",
    "            for i in range(len(nums)):\n",
    "                #if nums[i] not in vis:\n",
    "                if vis[i] == 0:\n",
    "                    q.append(nums[i])\n",
    "                    #print(q)\n",
    "                    #vis.add(nums[i])\n",
    "                    vis[i] = 1\n",
    "                    dfs(q)\n",
    "                    q.pop()\n",
    "                    #vis.remove(nums[i])\n",
    "                    vis[i] = 0\n",
    "        \n",
    "        res = []\n",
    "        #nums.sort()\n",
    "        #vis = set()\n",
    "        vis = [0]*len(nums)\n",
    "        st = set()\n",
    "        \n",
    "        dfs([])\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        li, res = [], []\n",
    "        seen = set()\n",
    "        def dfs(pos):\n",
    "            if pos==n:\n",
    "                x = tuple(li)\n",
    "                if  x not in seen:\n",
    "                    seen.add(x)\n",
    "                    res.append(li[:])\n",
    "                return\n",
    "            for i in range(pos,n):\n",
    "                \n",
    "                nums[pos],nums[i] = nums[i],nums[pos]\n",
    "                li.append(nums[pos])\n",
    "                dfs(pos+1)\n",
    "                li.pop()\n",
    "                nums[pos], nums[i] = nums[i],nums[pos]\n",
    "        dfs(0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        candidates = collections.deque(nums)\n",
    "        self.length = len(nums)\n",
    "        self.result = []\n",
    "        self.re = set()\n",
    "        def permutation(temp, l, candidate):\n",
    "            if self.length != l:\n",
    "                for _ in range(self.length-l):\n",
    "                    temp.append(candidate.popleft())\n",
    "                    permutation(temp, l+1, candidate)\n",
    "                    candidate.append(temp.pop())\n",
    "            else:\n",
    "                r = temp.copy()\n",
    "                t = tuple(r)\n",
    "                if t in self.re:\n",
    "                    return\n",
    "                self.result.append(r)\n",
    "                self.re.add(t)\n",
    "            return\n",
    "\n",
    "        permutation([], 0, candidates)\n",
    "        return self.result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def __init__(self):\n",
    "        self.path = []\n",
    "        self.results = []\n",
    "\n",
    "\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        self.traverslbacking(nums,len(nums))\n",
    "        return self.results\n",
    "    \n",
    "    \n",
    "    def traverslbacking(self,nums,lenth):\n",
    "        if len(self.path) == lenth:\n",
    "            self.results.append(self.path[:])\n",
    "        if  len(nums) == 0:\n",
    "            return None\n",
    "        chongfu_set = set()\n",
    "        for index in range(len(nums)):\n",
    "            if nums[index] not in chongfu_set:\n",
    "                chongfu_set.add(nums[index])\n",
    "                self.path.append(nums[index])\n",
    "                self.traverslbacking(nums[0:index]+nums[index+1:],lenth)\n",
    "                self.path.pop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        s = set()\n",
    "        for p in itertools.permutations(nums):\n",
    "            s.add(p)\n",
    "        return list(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        def backtrack(index):\n",
    "            if index == len(nums):\n",
    "                result.append(list(nums))\n",
    "                return\n",
    "            visited = set()\n",
    "            for i in range(index,len(nums)):\n",
    "                if nums[i] not in visited:\n",
    "                    visited.add(nums[i])\n",
    "                    nums[i],nums[index] = nums[index],nums[i]\n",
    "                    backtrack(index+1)\n",
    "                    nums[i],nums[index] = nums[index],nums[i]\n",
    "        result = []\n",
    "        backtrack(0)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        def f(i,nums,ans):\n",
    "            if i==len(nums):\n",
    "                ans.append(nums.copy())\n",
    "            else:\n",
    "                visit = set()\n",
    "                for j in range(i,len(nums)):\n",
    "                    if nums[j] not in visit:\n",
    "                        visit.add(nums[j])\n",
    "                        nums[i],nums[j] = nums[j],nums[i]\n",
    "                        f(i+1,nums,ans)\n",
    "                        nums[i],nums[j] = nums[j],nums[i]\n",
    "        ans = []\n",
    "        f(0,nums,ans)\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        res = []\n",
    "        self.process(nums, 0, res)\n",
    "        return res\n",
    "\n",
    "    def process(self, nums: List, i, res: List):\n",
    "        if i == len(nums):\n",
    "            # 添加结果时记得拷贝\n",
    "            res.append(copy.deepcopy(nums))\n",
    "            return None\n",
    "        \n",
    "        # 用于去重\n",
    "        existed = set()\n",
    "        for j in range(i, len(nums)):\n",
    "            if nums[j] not in existed:\n",
    "                existed.add(nums[j])\n",
    "                self.swap(nums, i, j)\n",
    "                self.process(nums, i+1, res)\n",
    "                self.swap(nums, j, i)\n",
    "    \n",
    "    def swap(self, lst, i, j):\n",
    "        lst[i], lst[j] = lst[j], lst[i]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "\n",
    "        res = []\n",
    "\n",
    "        def dfs(cur_nums, remain_nums):\n",
    "            if not remain_nums:\n",
    "                res.append(cur_nums)\n",
    "            \n",
    "            seen = set()\n",
    "            for i, num in enumerate(remain_nums):\n",
    "                if num in seen:\n",
    "                    continue\n",
    "                seen.add(num)\n",
    "                dfs(cur_nums + [num], remain_nums[:i] + remain_nums[i+1:])\n",
    "        \n",
    "        dfs([], nums)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        def dfs(x):\n",
    "            if x == n - 1:\n",
    "                res.append(list(nums))\n",
    "                return\n",
    "            st = set()\n",
    "            for i in range(x, n):\n",
    "                if nums[i] in st: continue\n",
    "                st.add(nums[i])\n",
    "                nums[i], nums[x] = nums[x], nums[i]\n",
    "                dfs(x + 1)\n",
    "                nums[i], nums[x] = nums[x], nums[i]\n",
    "        dfs(0)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        result = []\n",
    "        ln = len(nums)\n",
    "        def backtracking(pos: int):\n",
    "            if pos == ln:\n",
    "                result.append(nums[:])\n",
    "                return\n",
    "            # 当前位置元素选谁？\n",
    "            visited = set()\n",
    "            for i in range(pos, ln):\n",
    "                if nums[i] in visited:\n",
    "                    continue\n",
    "                visited.add(nums[i])\n",
    "                nums[pos], nums[i] = nums[i], nums[pos]\n",
    "                backtracking(pos + 1)\n",
    "                nums[pos], nums[i] = nums[i], nums[pos]\n",
    "            \n",
    "        backtracking(0)\n",
    "\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        ans = []\n",
    "        l = []\n",
    "        Len = len(nums)\n",
    "        PosNextValue, PosUse = defaultdict(set), dict()\n",
    "        \n",
    "        def Find(n, pre):\n",
    "            if n == Len:\n",
    "                ans.append(l.copy())\n",
    "                return\n",
    "            for i in range(Len):\n",
    "                if PosUse.get(i, -1) == -1:\n",
    "                    if nums[i] not in PosNextValue[pre]:\n",
    "                        PosNextValue[pre].add(nums[i])\n",
    "                        PosUse[i] = 1\n",
    "                        l.append(nums[i])\n",
    "                        Find(n + 1, i)\n",
    "                        l.pop()\n",
    "                        PosUse[i] = -1\n",
    "            PosNextValue[pre].clear()\n",
    "        Find(0, -1)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        n = len(nums)\n",
    "        vis = [False]*n\n",
    "        res = set()\n",
    "        path = []\n",
    "        def dfs(s):\n",
    "            if s == len(nums):\n",
    "                res.add(tuple(path[:]))\n",
    "            for i in range(n):\n",
    "                if vis[i] == False:\n",
    "                    path.append(nums[i])\n",
    "                    vis[i] = True\n",
    "                    dfs(s+1)\n",
    "                    vis[i] = False\n",
    "                    path.pop()\n",
    "        dfs(0)\n",
    "        res1 = sorted([list(i) for i in res])\n",
    "        return res1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        \n",
    "        def dfs(mark=0):\n",
    "            if mark == n-1:\n",
    "                res.append(nums[:])\n",
    "                return \n",
    "            vis = set()\n",
    "            for i in range(mark, n):\n",
    "                if nums[i] in vis: continue\n",
    "                vis.add(nums[i])\n",
    "                nums[i], nums[mark] = nums[mark], nums[i]\n",
    "                dfs(mark+1)\n",
    "                nums[i], nums[mark] = nums[mark], nums[i]\n",
    "        \n",
    "        n = len(nums)\n",
    "        res = []\n",
    "        dfs()\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def permuteUnique(self, nums: List[int]) -> List[List[int]]:\n",
    "        \n",
    "        labeled_set = set()\n",
    "        ans_set = set()\n",
    "\n",
    "        def recursion (cur_idx, temp_list):\n",
    "            labeled_set.add(cur_idx)\n",
    "            temp_list.append(nums[cur_idx])\n",
    "            if len(temp_list) == len(nums):\n",
    "                if tuple(temp_list) not in ans_set:\n",
    "                    ans_set.add(tuple(temp_list))\n",
    "            \n",
    "            for next_idx in range(len(nums)):\n",
    "                if next_idx not in labeled_set:\n",
    "                    recursion(next_idx, temp_list)\n",
    "            \n",
    "            labeled_set.remove(cur_idx)\n",
    "            temp_list.pop()\n",
    "            return\n",
    "        \n",
    "        for index in range(len(nums)):\n",
    "            recursion(index, [])\n",
    "        \n",
    "        return list(ans_set)\n",
    "        \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def sortList(self, head: ListNode) -> ListNode:\n",
    "        if not head:\n",
    "            return None\n",
    "        sl = SortedList()\n",
    "        step = 0\n",
    "        while head:\n",
    "            sl.add((head.val, step, head))\n",
    "            head = head.next\n",
    "            step += 1\n",
    "        prev = None\n",
    "        for _, _, node in sl:\n",
    "            if prev:\n",
    "                prev.next = node\n",
    "            if not head:\n",
    "                head = node\n",
    "            prev = node\n",
    "        prev.next = None\n",
    "        return head"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def add_node(self, val_list):\n",
    "        head = ListNode()\n",
    "        current = head\n",
    "        for val in val_list:\n",
    "            current.next = ListNode(val, current.next)\n",
    "            current = current.next\n",
    "\n",
    "        return ListNode(next=head).next.next\n",
    "\n",
    "    def sortList(self, head: ListNode) -> ListNode:\n",
    "        head = ListNode(next=head)\n",
    "        cur_node = head\n",
    "        new_list = []\n",
    "        while cur_node.next:\n",
    "            new_list.append(cur_node.next.val)\n",
    "            cur_node = cur_node.next\n",
    "        \n",
    "        new_list.sort()\n",
    "        return self.add_node(new_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        # 暴力解法\n",
    "        # for slow in range(len(nums)):\n",
    "        #     fast = slow+1\n",
    "        #     while fast <len(nums):\n",
    "        #         if abs(nums[slow] - nums[fast]) <=t and abs(slow-fast) <=k:\n",
    "        #             return True\n",
    "        #         else:\n",
    "        #             fast+=1\n",
    "        # return False\n",
    "        #滑动窗口\n",
    "#滑动窗口法 k作为滑动窗口的大小，如果超过了k 那么left行动\n",
    "        from sortedcontainers import SortedList\n",
    "        #排列好的集合\n",
    "        list_sort = SortedList()\n",
    "        ls=SortedList()\n",
    "        for left,num in enumerate(nums):\n",
    "            ls.add(num)\n",
    "            index = bisect_left(ls,num)\n",
    "            if index < len(ls)-1 and ls[index+1] - ls[index]<=t:return True\n",
    "            if index >0 and ls[index] - ls[index-1] <=t:return True\n",
    "            if len(ls) >k:\n",
    "                ls.remove(nums[left-k])\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        st = SortedList()\n",
    "        i = 0\n",
    "        for i,num in enumerate(nums):            \n",
    "            st.add(num)\n",
    "            index=bisect_left(st,num)\n",
    "            if index < len(st) - 1 and st[index+1] - st[index]<= t:\n",
    "                return True\n",
    "            if index > 0 and st[index] - st[index-1] <= t:\n",
    "                return True\n",
    "            if len(st) > k:\n",
    "                st.remove(nums[i-k])\n",
    "        return False\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# from sortedcontainers import SortedList\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        def get(x):\n",
    "            if x >= 0:\n",
    "                j = x // (t + 1)\n",
    "            else:\n",
    "                j = (x + 1) // (t + 1) - 1\n",
    "            return j\n",
    "        \n",
    "        m = {}\n",
    "        for i, x in enumerate(nums):   \n",
    "            j = get(x)\n",
    "            if j in m: \n",
    "                return True\n",
    "            l, r = j - 1, j + 1\n",
    "            if l in m and abs(m[l] - x) <= t: \n",
    "                return True\n",
    "            if r in m and abs(m[r] - x) <= t: \n",
    "                return True\n",
    "            m[j] = x\n",
    "            if i >= k:\n",
    "                m.pop(get(nums[i - k]))\n",
    "        return False\n",
    "        \n",
    "        # s = SortedList()\n",
    "        # for j, x in enumerate(nums):\n",
    "        #     if j > k:\n",
    "        #         s.discard(nums[j - k - 1])\n",
    "        #     s.add(x)\n",
    "        #     i = bisect_left(s, x)\n",
    "        #     if (i > 0 and s[i] - s[i - 1] <= t) or (i < len(s) - 1 and s[i + 1] - s[i] <= t):\n",
    "        #         return True\n",
    "        # return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        from sortedcontainers import SortedList\n",
    "        st = SortedList()\n",
    "        for i, num in enumerate(nums):\n",
    "\n",
    "            if len(st) == k+1:\n",
    "                st.remove(nums[i-k-1])\n",
    "            st.add(num)\n",
    "            # print(len(st))\n",
    "            index = bisect_left(st, num)\n",
    "            # print(st)\n",
    "            if index < len(st) - 1 and st[index + 1] - st[index] <=t: return True\n",
    "            if index >0 and st[index] - st[index-1] <=t: return True\n",
    "\n",
    "\n",
    "      \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        st = SortedList()\n",
    "        for i, num in enumerate(nums):            \n",
    "            st.add(num)\n",
    "            index = bisect_left(st, num)\n",
    "            if index < len(st) - 1 and st[index + 1] - st[index] <= t:\n",
    "                return True\n",
    "            if index > 0 and st[index] - st[index - 1] <= t:\n",
    "                return True\n",
    "            if len(st) > k:\n",
    "                st.remove(nums[i - k])\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        window=SortedList()\n",
    "        for i in range(len(nums)):\n",
    "            if i>k:\n",
    "                window.remove(nums[i-1-k])\n",
    "            window.add(nums[i])\n",
    "            idx=bisect.bisect_left(window,nums[i])\n",
    "            if idx>0 and abs(window[idx]-window[idx-1])<=t:\n",
    "                return True\n",
    "            if idx <len(window)-1 and abs(window[idx+1]-window[idx])<=t:\n",
    "                return True\n",
    "        return False \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        from sortedcontainers import SortedList\n",
    "        st = SortedList()\n",
    "        for i, num in enumerate(nums):\n",
    "\n",
    "            if len(st) == k+1:\n",
    "                st.remove(nums[i-k-1])\n",
    "            if num in st:\n",
    "                return True\n",
    "            st.add(num)\n",
    "            # print(len(st))\n",
    "            index = bisect_left(st, num)\n",
    "            # print(st)\n",
    "            if index < len(st) - 1 and st[index + 1] - st[index] <=t: return True\n",
    "            if index >0 and st[index] - st[index-1] <=t: return True\n",
    "\n",
    "\n",
    "      \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        from sortedcontainers import SortedList\n",
    "        st = SortedList()\n",
    "        for i,num in enumerate(nums):            \n",
    "            st.add(num)\n",
    "            index=bisect_left(st,num)\n",
    "            if index<len(st)-1 and st[index+1]-st[index]<=t:return True\n",
    "            if index>0 and st[index]-st[index-1]<=t:return True\n",
    "            if len(st)>k:\n",
    "                st.remove(nums[i-k])\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        from sortedcontainers import SortedList\n",
    "        st = SortedList()\n",
    "        for i , num in enumerate(nums):\n",
    "            st.add(num)\n",
    "            index = bisect_left(st,num)\n",
    "            if index < len(st) - 1 and st[index+1] - st[index]<=t:\n",
    "                return True\n",
    "            if index > 0 and st[index] - st[index -1] <= t:\n",
    "                return True\n",
    "            if len(st) > k:\n",
    "                st.remove(nums[i-k])\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        sort_list = SortedList([])\n",
    "        value_diff, index_diff = t, k\n",
    "\n",
    "        ans = 0\n",
    "        for i in range(len(nums)):\n",
    "            lower, upper = nums[i] - value_diff, nums[i] + value_diff\n",
    "            l = sort_list.bisect_left(lower)\n",
    "            r = sort_list.bisect_right(upper)\n",
    "            ans += r - l\n",
    "\n",
    "            # slide window\n",
    "            sort_list.add(nums[i])\n",
    "            if i-index_diff >= 0:\n",
    "                sort_list.remove(nums[i-index_diff])\n",
    "            \n",
    "        return ans >= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        if not nums or k==0:\n",
    "            return False\n",
    "        array=[nums[0]]\n",
    "        left=0\n",
    "        right=1\n",
    "        array=SortedList(array)\n",
    "        while right<len(nums):\n",
    "            index=bisect_left(array,nums[right])\n",
    "            if index==0:\n",
    "                if abs(nums[right]-array[index])<=t:\n",
    "                    return True\n",
    "            elif index==len(array):\n",
    "                if abs(nums[right]-array[index-1])<=t:\n",
    "                    return True\n",
    "            else:\n",
    "                if abs(nums[right]-array[index])<=t or abs(nums[right]-array[index-1])<= t:\n",
    "                    return True\n",
    "            array.add(nums[right])\n",
    "            right+=1\n",
    "            if right-left>k:\n",
    "                array.remove(nums[left])\n",
    "                left+=1\n",
    "        \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        from bisect import bisect_left\n",
    "        from sortedcontainers import SortedList\n",
    "        INT_MIN = - 1 << 31\n",
    "        INT_MAX = -INT_MIN - 1\n",
    "        n = len(nums)\n",
    "        s = SortedList()\n",
    "        for i in range(n):\n",
    "            # 大于等于x-t的最小元素, 这里注意越界情况\n",
    "            idx = bisect_left(s, max(nums[i], INT_MIN+t)-t)\n",
    "            if idx != len(s) and s[idx] <= min(nums[i], INT_MAX-t) + t:\n",
    "                return True\n",
    "            s.add(nums[i])\n",
    "            if i >= k:\n",
    "                s.remove(nums[i-k])\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "import bisect\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        if k == 0:\n",
    "            return False\n",
    "\n",
    "        sl = SortedList()\n",
    "\n",
    "        lens = len(nums)\n",
    "        l = 0\n",
    "        for r in range(lens):\n",
    "            if r - l <= k and sl:\n",
    "                rights = max(min(bisect.bisect_left(sl, nums[r]), len(sl) - 1), 0)\n",
    "                lefts = max(rights - 1, 0)\n",
    "\n",
    "                if abs(nums[r] - sl[lefts]) <= t or abs(nums[r] - sl[rights]) <= t:\n",
    "                    return True\n",
    "\n",
    "            if r - l == k:\n",
    "                sl.remove(nums[l])\n",
    "                l += 1\n",
    "\n",
    "            sl.add(nums[r])\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        s = SortedList()\n",
    "        for j, x in enumerate(nums):\n",
    "            if j > k:\n",
    "                s.discard(nums[j - k - 1])\n",
    "            s.add(x)\n",
    "            i = bisect_left(s, x)\n",
    "            if (i > 0 and s[i] - s[i - 1] <= t) or (i < len(s) - 1 and s[i + 1] - s[i] <= t):\n",
    "                return True\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        from sortedcontainers import SortedList\n",
    "        st = SortedList()\n",
    "        for i , num in enumerate(nums):\n",
    "            st.add(num)\n",
    "            index = bisect_left(st,num)\n",
    "            if index < len(st) - 1 and st[index+1] - st[index]<=t:\n",
    "                return True\n",
    "            if index > 0 and st[index] - st[index -1] <= t:\n",
    "                return True\n",
    "            if len(st) > k:\n",
    "                st.remove(nums[i-k])\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "\n",
    "# nums[0] - nums[k] <= t = 10\n",
    "from typing import List\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        n = len(nums)\n",
    "        sort_list = SortedList([])\n",
    "        idx_diff, value_diff = k, t\n",
    "\n",
    "        ans = 0\n",
    "        for i in range(n):\n",
    "            # calculate \n",
    "            lower = nums[i] - value_diff\n",
    "            upper = nums[i] + value_diff\n",
    "            l = sort_list.bisect_left(lower)\n",
    "            r = sort_list.bisect_right(upper)\n",
    "            ans += r-l\n",
    "\n",
    "            # slide window \n",
    "            sort_list.add(nums[i])\n",
    "            if i-idx_diff >= 0:\n",
    "                sort_list.remove(nums[i-idx_diff])\n",
    "\n",
    "        return ans >= 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], indexDiff: int, valueDiff: int) -> bool:\n",
    "        if len(nums) < 2:\n",
    "            return False\n",
    "        if indexDiff == 0:\n",
    "            return False\n",
    "        window = SortedList([nums[0]])\n",
    "        for i in range(1, len(nums)):\n",
    "            left = nums[i] - valueDiff\n",
    "            right = nums[i] + valueDiff\n",
    "            if left <= window[-1] and right >= window[0]:\n",
    "                left_pos = window.bisect_left(left)\n",
    "                right_pos = window.bisect_right(right)\n",
    "                if left_pos < right_pos:\n",
    "                    return True\n",
    "                if window[left_pos] >= left and window[left_pos] <= right:\n",
    "                    return True\n",
    "            if len(window) >= indexDiff:\n",
    "                window.remove(nums[i - indexDiff])\n",
    "            window.add(nums[i])\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        n = len(nums)\n",
    "        sl = SortedList()\n",
    "        for r in range(n):\n",
    "            p = bisect_left(sl, nums[r])\n",
    "            if p != len(sl) and abs(sl[p] - nums[r]) <= t: return True\n",
    "            if p != 0 and abs(sl[p - 1] - nums[r]) <= t: return True\n",
    "            sl.add(nums[r])\n",
    "            if r >= k:\n",
    "                sl.remove(nums[r - k])\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import *\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        sl = SortedList([-inf, inf])\n",
    "        dq = deque()\n",
    "        for x in nums:\n",
    "            dq.append(x)\n",
    "            if len(dq) > k+1: sl.remove(dq.popleft())\n",
    "            p = sl.bisect_left(x)\n",
    "            if x-sl[p-1] <= t or sl[p] - x <= t: return True\n",
    "            sl.add(x)\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums, k: int, t: int) -> bool:\n",
    "        if len(nums)<=1 or k==0:\n",
    "            return False\n",
    "        lis=SortedList()\n",
    "        \n",
    "        for i in range(len(nums)):\n",
    "            p=lis.bisect_right(nums[i])\n",
    "            if p-1>=0:\n",
    "                if nums[i]-lis[p-1]<=t:\n",
    "                    return True\n",
    "            if p<len(lis):\n",
    "                if  lis[p]-nums[i] <= t:\n",
    "                    return True\n",
    "            lis.add(nums[i])\n",
    "            if len(lis)>k:\n",
    "                lis.discard(nums[i-k])\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedList\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], c: int, t: int) -> bool:\n",
    "        l = SortedList()\n",
    "        i = 0\n",
    "        dic = {}\n",
    "        for j in range(0, len(nums)):\n",
    "            cur = nums[j]\n",
    "            # print(j, i, j - i)\n",
    "            while (j - i > c):\n",
    "                prev = nums[i]\n",
    "                dic[prev] -= 1\n",
    "                print(\"asd\")\n",
    "                if dic[prev] == 0:\n",
    "                    l.remove(prev)\n",
    "                i += 1\n",
    "            # print(dic)\n",
    "            if len(l) > 0:\n",
    "                a = l.bisect_left(cur)\n",
    "                b = l.bisect_right(cur)\n",
    "                options = [a, b, a + 1, a - 1, b + 1, b - 1]\n",
    "                # print(l, cur)\n",
    "                for k in range(0, len(options)):\n",
    "                    index = options[k]\n",
    "                    if index >= 0 and index < len(l) and abs(l[index] - cur) <= t:\n",
    "                        return True\n",
    "            if cur not in dic:\n",
    "                dic[cur] = 0\n",
    "            l.add(cur)\n",
    "            dic[cur] += 1 \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        from sortedcontainers import SortedSet\n",
    "        if len(nums) < k + 1:\n",
    "            myset = SortedSet(nums)\n",
    "        else:\n",
    "            myset = SortedSet(nums[:k + 1])\n",
    "        if len(myset) < min(len(nums), k + 1):\n",
    "            return True\n",
    "        for i in range(len(myset) - 1):\n",
    "            if myset[i + 1] - myset[i] <= t:\n",
    "                return True\n",
    "        for i in range(k + 1, len(nums)):\n",
    "            myset.remove(nums[i - k - 1])\n",
    "            if nums[i] in myset:\n",
    "                return True\n",
    "            myset.add(nums[i])\n",
    "            tempindex = myset.index(nums[i])\n",
    "            if tempindex > 0 and nums[i] - myset[tempindex - 1] <= t:\n",
    "                return True\n",
    "            if tempindex < len(myset) - 1 and myset[tempindex + 1] - nums[i] <= t:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedSet\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        if not nums: return False\n",
    "        if k == 0: return False\n",
    "        n=len(nums)\n",
    "        k = min(n-1,k)\n",
    "        sst = SortedSet()\n",
    "        for i in range(k+1):\n",
    "            a = nums[i]\n",
    "            l,r = a-t,a+t\n",
    "            pl,pr=sst.bisect_left(l),sst.bisect_left(r)\n",
    "            if pl < pr: return True\n",
    "            if pr<len(sst) and sst[pr]==r: return True\n",
    "            sst.add(a)\n",
    "        for i in range(1,n-k):\n",
    "            b,a = nums[i-1],nums[i+k]\n",
    "            sst.discard(b)\n",
    "            l,r = a-t,a+t\n",
    "            pl,pr=sst.bisect_left(l),sst.bisect_left(r)\n",
    "            if pl < pr: return True\n",
    "            if pr<len(sst) and sst[pr]==r: return True\n",
    "            sst.add(a)\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedSet\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        if not nums: return False\n",
    "        if k == 0: return False\n",
    "        n=len(nums)\n",
    "        k = min(n-1,k)\n",
    "        sst = SortedSet()\n",
    "        for i in range(k+1):\n",
    "            a = nums[i]\n",
    "            l,r = a-t,a+t\n",
    "            pl,pr=sst.bisect_left(l),sst.bisect_left(r)\n",
    "            if pl < pr: return True\n",
    "            if pr<len(sst) and sst[pr]==r: return True\n",
    "            sst.add(a)\n",
    "        for i in range(1,n-k):\n",
    "            b,a = nums[i-1],nums[i+k]\n",
    "            sst.discard(b)\n",
    "            l,r = a-t,a+t\n",
    "            pl,pr=sst.bisect_left(l),sst.bisect_left(r)\n",
    "            if pl < pr: return True\n",
    "            if pr<len(sst) and sst[pr]==r: return True\n",
    "            sst.add(a)\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from sortedcontainers import SortedSet\n",
    "class Solution:\n",
    "    def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:\n",
    "        s = SortedSet()\n",
    "        for i, num in enumerate(nums):\n",
    "            idx = s.bisect_left(num-t)\n",
    "            if 0<=idx <len(s) and s[idx]<=num+t:\n",
    "                return True\n",
    "            s.add(num)\n",
    "            if i>=k:\n",
    "                s.remove(nums[i-k])\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def evalRPN(self, tokens: List[str]) -> int:\n",
    "        op_to_binary_fn = {\n",
    "            \"+\": add,\n",
    "            \"-\": sub,\n",
    "            \"*\": mul,\n",
    "            \"/\": lambda x, y: int(x / y),   # 需要注意 python 中负数除法的表现与题目不一致\n",
    "        }\n",
    "\n",
    "        stack = list()\n",
    "        for token in tokens:\n",
    "            try:\n",
    "                num = int(token)\n",
    "            except ValueError:\n",
    "                num2 = stack.pop()\n",
    "                num1 = stack.pop()\n",
    "                num = op_to_binary_fn[token](num1, num2)\n",
    "            finally:\n",
    "                stack.append(num)\n",
    "            \n",
    "        return stack[0]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # '/': lambda x, y: int(x / y)\n",
    "    op_map = {'+': add, '-': sub, '*': mul, '/': lambda x, y: int(x / y)}\n",
    "    def evalRPN(self, tokens: List[str]) -> int:\n",
    "        stack = []\n",
    "        for token in tokens:\n",
    "            if token not in ['+',\"-\",\"*\",\"/\"]:\n",
    "                stack.append(int(token))\n",
    "            else:\n",
    "                num2 = stack.pop()\n",
    "                num1 = stack.pop()\n",
    "                stack.append(self.op_map[token](num1, num2))\n",
    "        return stack.pop()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "from operator import add, sub, mul\n",
    "\n",
    "class Solution:\n",
    "    def evalRPN(self, tokens: List[str]) -> int:\n",
    "        op_to_binary_fn = {\n",
    "            \"+\": add,\n",
    "            \"-\": sub,\n",
    "            \"*\": mul,\n",
    "            \"/\": lambda x, y: int(x / y)  # 由于只需要整数部分，特别处理除法\n",
    "        }\n",
    "\n",
    "        stack = []\n",
    "        for token in tokens:\n",
    "            try:\n",
    "                num = int(token)  # 尝试将标记转换为整数\n",
    "            except ValueError:  # 如果转换失败，说明是运算符\n",
    "                num2 = stack.pop()\n",
    "                num1 = stack.pop()\n",
    "                num = op_to_binary_fn[token](num1, num2)  # 应用运算符进行计算\n",
    "            finally:\n",
    "                stack.append(num)  # 将结果压回栈中\n",
    "\n",
    "        return stack[0]  # 最终的计算结果在栈顶\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def evalRPN(self, tokens: List[str]) -> int:\n",
    "        op_to_binary_fn = {\n",
    "            \"+\": add,\n",
    "            \"-\": sub,\n",
    "            \"*\": mul,\n",
    "            \"/\": lambda x, y: int(x / y),   # 需要注意 python 中负数除法的表现与题目不一致\n",
    "        }\n",
    "\n",
    "        n = len(tokens)\n",
    "        stack = [0] * ((n + 1) // 2)\n",
    "        index = -1\n",
    "        for token in tokens:\n",
    "            try:\n",
    "                num = int(token)\n",
    "                index += 1\n",
    "                stack[index] = num\n",
    "            except ValueError:\n",
    "                index -= 1\n",
    "                stack[index] = op_to_binary_fn[token](stack[index], stack[index + 1])\n",
    "            \n",
    "        return stack[0]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    op_map = {'+':add,'-':sub,'*':mul,'/':lambda x,y:int(x/y)}\n",
    "    def evalRPN(self, tokens: List[str]) -> int:\n",
    "        stack = []\n",
    "        for token in tokens:\n",
    "            if token not in ['+','-','*','/']:\n",
    "                stack.append(int(token))\n",
    "            else:\n",
    "                num2 = stack.pop()\n",
    "                num1 = stack.pop()\n",
    "                stack.append(self.op_map[token](num1,num2))\n",
    "        return stack.pop()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        pre = 0\n",
    "        mp = dict()\n",
    "        mp_set = set()\n",
    "        mp[0] = -1\n",
    "        mp_set.add(0)\n",
    "        ans = -1\n",
    "        for idx, x in enumerate(nums):\n",
    "            if x:\n",
    "                pre += 1\n",
    "            else:\n",
    "                pre -= 1\n",
    "            if pre in mp_set:\n",
    "                if ans < idx - mp[pre]:\n",
    "                    ans = idx - mp[pre]\n",
    "            else:\n",
    "                mp[pre] = idx\n",
    "                mp_set.add(pre)\n",
    "        if ans < 0:\n",
    "            return 0\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def findMaxLength(self, nums: List[int]) -> int:\n",
    "        preSum = []\n",
    "        preSum.append(1 if nums[0] == 1 else -1)\n",
    "        for i in range(1,len(nums)):\n",
    "            add = 1 if nums[i] == 1 else -1\n",
    "            preSum.append(preSum[i-1] + add)\n",
    "\n",
    "        dict = {}\n",
    "        ans = 0\n",
    "        for i,x in enumerate(preSum):\n",
    "            if x == 0:\n",
    "                ans = max(i+1,ans)\n",
    "            elif x in dict:\n",
    "                ans = max(i-dict[x],ans)\n",
    "            if x not in dict:\n",
    "                dict[x] = i\n",
    "            else:\n",
    "                dict[x] = min(dict[x],i)\n",
    "        return ans\n",
    "\n",
    "            \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        is_pa = set()\n",
    "        count = 0\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i+1):\n",
    "                if s[i]==s[j]:\n",
    "                    if i-j<=2 or (j+1,i-1) in is_pa:\n",
    "                        is_pa.add((j,i))\n",
    "                        count = count +1\n",
    "        return count\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        res = n\n",
    "        def ishuiwen(s):\n",
    "            if s[::-1]==s:\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        ans=0\n",
    "        set_s = set()\n",
    "        for i in range(n):\n",
    "            for j in range(i,n+1):\n",
    "                s_s = s[i:j]\n",
    "                if ishuiwen(s_s) and (i,j) not in set_s and i!=j:\n",
    "                    set_s.add((i,j))\n",
    "                   \n",
    "                    ans+=1\n",
    "        # print(set_s)\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        dq = deque()\n",
    "        seen = set()\n",
    "        for i in range(n):\n",
    "            dq.append((i, i))\n",
    "            seen.add((i, i))\n",
    "        for i in range(n - 1):\n",
    "            if s[i] == s[i + 1]:\n",
    "                dq.append((i, i + 1))\n",
    "                seen.add((i, i + 1))\n",
    "        \n",
    "        count = 0\n",
    "        while dq:\n",
    "            x, y = dq.popleft()\n",
    "            count += 1\n",
    "            if 0 <= x - 1 < n and 0 <= y + 1 < n:\n",
    "                if s[x - 1] == s[y + 1]:\n",
    "                    dq.append((x - 1, y + 1))\n",
    "                    seen.add((x - 1, y + 1))\n",
    "        return count\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "        ans = 0\n",
    "        visit = set()\n",
    "        \n",
    "        def dfs(start, end):\n",
    "            if (start, end) in visit:\n",
    "                return\n",
    "            nonlocal ans\n",
    "            if start>end:\n",
    "                return True\n",
    "            if s[start]==s[end]:\n",
    "                if end-start+1<3:\n",
    "                    if (start, end) not in visit:\n",
    "                        visit.add((start, end))\n",
    "                        ans += 1\n",
    "                    return True \n",
    "                else:\n",
    "                    if dfs(start+1,end-1):\n",
    "                        visit.add((start, end))\n",
    "                        ans += 1\n",
    "                        return True\n",
    "            return False\n",
    "\n",
    "        for i in range(0,n-1):\n",
    "            for j in range(i,n):\n",
    "                dfs(i,j)\n",
    "        return ans+1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def countSubstrings(self, s: str) -> int:\n",
    "        n = len(s)\n",
    "    \n",
    "        dp =  [ [False] * (1 + n) for _ in range(1 + n)]\n",
    "        ans = set()\n",
    "        for L in range(1, 1 + n):\n",
    "            for i in range(n):\n",
    "                j = L + i -1\n",
    "                if j < n:\n",
    "                    if s[i] == s[j]:\n",
    "                        if j - i + 1 <= 3:\n",
    "                            dp[i][j] = True\n",
    "                        else:\n",
    "                            dp[i][j] = dp[i+1][j-1]\n",
    "                        if dp[i][j]:\n",
    "                            ans.add((i, j))\n",
    "        return len(ans)\n",
    "    \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self):\n",
    "        self.father = {}\n",
    "        # 根节点所在集合的所有账户\n",
    "        self.accounts = {}\n",
    "        \n",
    "    def find(self,x):\n",
    "        if not self.father[x]: return x\n",
    "        \n",
    "        # 递归的路径压缩处理\n",
    "        self.father[x] = self.find(self.father[x])\n",
    "        \n",
    "        return self.father[x]\n",
    "    \n",
    "    def merge(self,x,y):\n",
    "        root_x,root_y = self.find(x),self.find(y)\n",
    "        \n",
    "        if root_x == root_y:\n",
    "            return\n",
    "        \n",
    "        # 按秩合并，更新根节点和所属的账户\n",
    "        if len(self.accounts[root_x]) > len(self.accounts[root_y]):\n",
    "            self.father[root_y] = root_x\n",
    "            self.accounts[root_x] += self.accounts[root_y]\n",
    "            del self.accounts[root_y]\n",
    "        else:\n",
    "            self.father[root_x] = root_y\n",
    "            self.accounts[root_y] += self.accounts[root_x]\n",
    "            del self.accounts[root_x]\n",
    "    \n",
    "    def add(self,x):\n",
    "        if x not in self.father:\n",
    "            self.father[x] = None\n",
    "            self.accounts[x] = [x]\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf = UnionFind()\n",
    "        for account in accounts:\n",
    "            # 找到姓名和主账户\n",
    "            name,master = account[0],account[1]\n",
    "            uf.add((name,master))\n",
    "            \n",
    "            # 和其余的账户一一合并\n",
    "            account = list(set(account[2:]))\n",
    "            for i in range(len(account)):\n",
    "                uf.add((name,account[i]))\n",
    "                uf.merge((name,master),(name,account[i]))\n",
    "        \n",
    "        res = []\n",
    "        for key,value in uf.father.items():\n",
    "            # 是根节点\n",
    "            if not value:\n",
    "                # 添加user\n",
    "                usr = [uf.accounts[key][0][0]]\n",
    "                acc = []\n",
    "                # 添加账户\n",
    "                for account in uf.accounts[key]:\n",
    "                    acc.append(account[1])\n",
    "                    \n",
    "                res.append(usr + sorted(acc))\n",
    "                \n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self):\n",
    "        self.father = {}\n",
    "        # 根节点所在集合的所有账户\n",
    "        self.accounts = {}\n",
    "        \n",
    "    def find(self,x):\n",
    "        if not self.father[x]: return x\n",
    "        \n",
    "        # 递归的路径压缩处理\n",
    "        self.father[x] = self.find(self.father[x])\n",
    "        \n",
    "        return self.father[x]\n",
    "    \n",
    "    def merge(self,x,y):\n",
    "        root_x,root_y = self.find(x),self.find(y)\n",
    "        \n",
    "        if root_x == root_y:\n",
    "            return\n",
    "        \n",
    "        # 按秩合并，更新根节点和所属的账户\n",
    "        if len(self.accounts[root_x]) > len(self.accounts[root_y]):\n",
    "            self.father[root_y] = root_x\n",
    "            self.accounts[root_x] += self.accounts[root_y]\n",
    "            del self.accounts[root_y]\n",
    "        else:\n",
    "            self.father[root_x] = root_y\n",
    "            self.accounts[root_y] += self.accounts[root_x]\n",
    "            del self.accounts[root_x]\n",
    "    \n",
    "    def add(self,x):\n",
    "        if x not in self.father:\n",
    "            self.father[x] = None\n",
    "            self.accounts[x] = [x]\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf = UnionFind()\n",
    "        for account in accounts:\n",
    "            # 找到姓名和主账户\n",
    "            name,master = account[0],account[1]\n",
    "            uf.add((name,master))\n",
    "            \n",
    "            # 和其余的账户一一合并\n",
    "            account = list(set(account[2:]))\n",
    "            for i in range(len(account)):\n",
    "                uf.add((name,account[i]))\n",
    "                uf.merge((name,master),(name,account[i]))\n",
    "        \n",
    "        res = []\n",
    "        for key,value in uf.father.items():\n",
    "            # 是根节点\n",
    "            if not value:\n",
    "                # 添加user\n",
    "                usr = [uf.accounts[key][0][0]]\n",
    "                acc = []\n",
    "                # 添加账户\n",
    "                for account in uf.accounts[key]:\n",
    "                    acc.append(account[1])\n",
    "                    \n",
    "                res.append(usr + sorted(acc))\n",
    "                \n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def build_graph(self,accounts):\n",
    "        # 构建无向图，每个邮箱为一个节点，同一个账户的邮箱全部相连\n",
    "        # 有多少连通分量，就有多少独立的账户\n",
    "        # 该字典，键为一个邮箱，值为与其相连的所有邮箱\n",
    "        graph = collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            master = account[1]\n",
    "            # 对剩余账户做一个去重\n",
    "            for email in list(set(account[2:])):\n",
    "                graph[master].append(email)\n",
    "                graph[email].append(master)\n",
    "        \n",
    "        return graph\n",
    "    \n",
    "    def dfs(self,email,graph,visited,emails):\n",
    "        \"\"\"\n",
    "        深搜遍历\n",
    "        \"\"\"\n",
    "        # 已经访问过的就剪枝\n",
    "        if email in visited:\n",
    "            return \n",
    "        \n",
    "        visited.add(email)\n",
    "        emails.append(email)\n",
    "        \n",
    "        # 对邻居节点继续深搜\n",
    "        for neighbor in graph[email]:\n",
    "            self.dfs(neighbor,graph,visited,emails)\n",
    "    \n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        graph = self.build_graph(accounts)\n",
    "\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            emails = []# 存储该账户的所有邮箱\n",
    "            # 深度优先遍历，作为键的第一个邮箱如果已经被前者关联，则直接剪枝\n",
    "            self.dfs(account[1],graph,visited,emails)\n",
    "            #如果是相同用户出现过了，则全会被剪枝，res不会添加\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        \n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "\n",
    "    def __init__(self):\n",
    "\n",
    "        self.father = {}\n",
    "\n",
    "        # 根节点所在集合的所有账户\n",
    "\n",
    "        self.accounts = {}\n",
    "\n",
    "        \n",
    "\n",
    "    def find(self,x):\n",
    "\n",
    "        if not self.father[x]: return x\n",
    "\n",
    "        \n",
    "\n",
    "        # 递归的路径压缩处理\n",
    "\n",
    "        self.father[x] = self.find(self.father[x])\n",
    "\n",
    "        \n",
    "\n",
    "        return self.father[x]\n",
    "\n",
    "    \n",
    "\n",
    "    def merge(self,x,y):\n",
    "\n",
    "        root_x,root_y = self.find(x),self.find(y)\n",
    "\n",
    "        \n",
    "\n",
    "        if root_x == root_y:\n",
    "\n",
    "            return\n",
    "\n",
    "        \n",
    "\n",
    "        # 按秩合并，更新根节点和所属的账户\n",
    "\n",
    "        if len(self.accounts[root_x]) > len(self.accounts[root_y]):\n",
    "\n",
    "            self.father[root_y] = root_x\n",
    "\n",
    "            self.accounts[root_x] += self.accounts[root_y]\n",
    "\n",
    "            del self.accounts[root_y]\n",
    "\n",
    "        else:\n",
    "\n",
    "            self.father[root_x] = root_y\n",
    "\n",
    "            self.accounts[root_y] += self.accounts[root_x]\n",
    "\n",
    "            del self.accounts[root_x]\n",
    "\n",
    "    \n",
    "\n",
    "    def add(self,x):\n",
    "\n",
    "        if x not in self.father:\n",
    "\n",
    "            self.father[x] = None\n",
    "\n",
    "            self.accounts[x] = [x]\n",
    "\n",
    "\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "\n",
    "        uf = UnionFind()\n",
    "\n",
    "        for account in accounts:\n",
    "\n",
    "            # 找到姓名和主账户\n",
    "\n",
    "            name,master = account[0],account[1]\n",
    "\n",
    "            uf.add((name,master))\n",
    "\n",
    "            \n",
    "\n",
    "            # 和其余的账户一一合并\n",
    "\n",
    "            account = list(account[2:])\n",
    "\n",
    "            for i in range(len(account)):\n",
    "\n",
    "                uf.add((name,account[i]))\n",
    "\n",
    "                uf.merge((name,master),(name,account[i]))\n",
    "\n",
    "        \n",
    "\n",
    "        res = []\n",
    "\n",
    "        for key,value in uf.father.items():\n",
    "\n",
    "            # 是根节点\n",
    "\n",
    "            if not value:\n",
    "\n",
    "                # 添加user\n",
    "\n",
    "                usr = [uf.accounts[key][0][0]]\n",
    "\n",
    "                acc = []\n",
    "\n",
    "                # 添加账户\n",
    "\n",
    "                for account in uf.accounts[key]:\n",
    "\n",
    "                    acc.append(account[1])\n",
    "\n",
    "                    \n",
    "\n",
    "                res.append(usr + sorted(acc))\n",
    "\n",
    "                \n",
    "\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "                \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#copy\n",
    "class unionfind:\n",
    "    def __init__(self):\n",
    "        self.father = {}\n",
    "        self.accounts = {}\n",
    "    def find(self,x):\n",
    "        if not self.father[x]:\n",
    "            return x\n",
    "        self.father[x]=  self.find(self.father[x])\n",
    "        return self.father[x]\n",
    "    def merge(self,x,y):\n",
    "        rootx,rooty = self.find(x),self.find(y)\n",
    "        if rootx == rooty:\n",
    "            return \n",
    "        if len(self.accounts[rootx]) > len(self.accounts[rooty]):\n",
    "            self.father[rooty] = rootx\n",
    "            self.accounts[rootx] += self.accounts[rooty]\n",
    "            del self.accounts[rooty]\n",
    "        else:\n",
    "            self.father[rootx] = rooty\n",
    "            self.accounts[rooty] += self.accounts[rootx]\n",
    "            del self.accounts[rootx]\n",
    "    def add(self,x):\n",
    "        if x not in self.father:\n",
    "            self.father[x] = None\n",
    "            self.accounts[x] =[x]\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf = unionfind()\n",
    "        for account in accounts:\n",
    "            name,master = account[0],account[1]\n",
    "            uf.add((name,master))\n",
    "\n",
    "            account = list(set(account[2:]))\n",
    "            for i in range(len(account)):\n",
    "                uf.add((name,account[i]))\n",
    "                uf.merge((name,master),(name,account[i]))\n",
    "        res = []\n",
    "        for k,v in uf.father.items():\n",
    "            if not v:\n",
    "                usr = [uf.accounts[k][0][0]]\n",
    "                acc = []\n",
    "                for account in uf.accounts[k]:\n",
    "                    acc.append(account[1])\n",
    "                \n",
    "                res.append(usr+ sorted(acc))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self):\n",
    "        self.father = {}\n",
    "        # 根节点所在集合的所有账户\n",
    "        self.accounts = {}\n",
    "        \n",
    "    def find(self,x):\n",
    "        if not self.father[x]: return x\n",
    "        \n",
    "        # 递归的路径压缩处理\n",
    "        self.father[x] = self.find(self.father[x])\n",
    "        \n",
    "        return self.father[x]\n",
    "    \n",
    "    def merge(self,x,y):\n",
    "        root_x,root_y = self.find(x),self.find(y)\n",
    "        \n",
    "        if root_x == root_y:\n",
    "            return\n",
    "        \n",
    "        # 按秩合并，更新根节点和所属的账户\n",
    "        if len(self.accounts[root_x]) > len(self.accounts[root_y]):\n",
    "            self.father[root_y] = root_x\n",
    "            self.accounts[root_x] += self.accounts[root_y]\n",
    "            del self.accounts[root_y]\n",
    "        else:\n",
    "            self.father[root_x] = root_y\n",
    "            self.accounts[root_y] += self.accounts[root_x]\n",
    "            del self.accounts[root_x]\n",
    "    \n",
    "    def add(self,x):\n",
    "        if x not in self.father:\n",
    "            self.father[x] = None\n",
    "            self.accounts[x] = [x]\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf = UnionFind()\n",
    "        for account in accounts:\n",
    "            # 找到姓名和主账户\n",
    "            name,master = account[0],account[1]\n",
    "            uf.add((name,master))\n",
    "            \n",
    "            # 和其余的账户一一合并\n",
    "            account = list(set(account[2:]))\n",
    "            for i in range(len(account)):\n",
    "                uf.add((name,account[i]))\n",
    "                uf.merge((name,master),(name,account[i]))\n",
    "        \n",
    "        res = []\n",
    "        for key,value in uf.father.items():\n",
    "            # 是根节点\n",
    "            if not value:\n",
    "                # 添加user\n",
    "                usr = [uf.accounts[key][0][0]]\n",
    "                acc = []\n",
    "                # 添加账户\n",
    "                for account in uf.accounts[key]:\n",
    "                    acc.append(account[1])\n",
    "                    \n",
    "                res.append(usr + sorted(acc))\n",
    "                \n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self):\n",
    "        self.father={}\n",
    "        self.account={}\n",
    "        \n",
    "    def find(self, x):\n",
    "        if not self.father[x]:\n",
    "            return x\n",
    "        self.father[x]=self.find(self.father[x])\n",
    "        return self.father[x]\n",
    "    \n",
    "    def merge(self, x, y):\n",
    "        px, py=self.find(x), self.find(y)\n",
    "        if px == py:\n",
    "            return\n",
    "        \n",
    "        if len(self.account[px])>len(self.account[py]):\n",
    "            self.father[py]=px\n",
    "            self.account[px] += self.account[py]\n",
    "            del self.account[py]\n",
    "        else:\n",
    "            self.father[px]=py\n",
    "            self.account[py] += self.account[px]\n",
    "            del self.account[px]\n",
    "    \n",
    "    def add(self, x):\n",
    "        if x not in self.father:\n",
    "            self.father[x]=None\n",
    "            self.account[x]=[x]\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf=UnionFind()\n",
    "        for account in accounts:\n",
    "            name, master=account[0],account[1]\n",
    "            uf.add((name, master))\n",
    "            account=list(set(account[2:]))\n",
    "            for i in range(len(account)):\n",
    "                uf.add((name, account[i]))\n",
    "                uf.merge((name, master), (name, account[i]))\n",
    "        res=[]\n",
    "        for key, val in uf.father.items():\n",
    "            if not val:\n",
    "                usr=[uf.account[key][0][0]]\n",
    "                acc=[]\n",
    "                for a in uf.account[key]:\n",
    "                    acc.append(a[1])\n",
    "                res.append(usr+sorted(acc))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self):\n",
    "        self.father = {}\n",
    "        # 根节点所在集合的所有账户\n",
    "        self.accounts = {}\n",
    "        \n",
    "    def find(self,x):\n",
    "        if not self.father[x]: return x\n",
    "        \n",
    "        # 递归的路径压缩处理\n",
    "        self.father[x] = self.find(self.father[x])\n",
    "        \n",
    "        return self.father[x]\n",
    "    \n",
    "    def merge(self,x,y):\n",
    "        root_x,root_y = self.find(x),self.find(y)\n",
    "        \n",
    "        if root_x == root_y:\n",
    "            return\n",
    "        \n",
    "        # 按秩合并，更新根节点和所属的账户\n",
    "        if len(self.accounts[root_x]) > len(self.accounts[root_y]):\n",
    "            self.father[root_y] = root_x\n",
    "            self.accounts[root_x] += self.accounts[root_y]\n",
    "            del self.accounts[root_y]\n",
    "        else:\n",
    "            self.father[root_x] = root_y\n",
    "            self.accounts[root_y] += self.accounts[root_x]\n",
    "            del self.accounts[root_x]\n",
    "    \n",
    "    def add(self,x):\n",
    "        if x not in self.father:\n",
    "            self.father[x] = None\n",
    "            self.accounts[x] = [x]\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf = UnionFind()\n",
    "        for account in accounts:\n",
    "            # 找到姓名和主账户\n",
    "            name,master = account[0],account[1]\n",
    "            uf.add((name,master))\n",
    "            \n",
    "            # 和其余的账户一一合并\n",
    "            account = list(set(account[2:]))\n",
    "            for i in range(len(account)):\n",
    "                uf.add((name,account[i]))\n",
    "                uf.merge((name,master),(name,account[i]))\n",
    "        \n",
    "        res = []\n",
    "        for key,value in uf.father.items():\n",
    "            # 是根节点\n",
    "            if not value:\n",
    "                # 添加user\n",
    "                usr = [uf.accounts[key][0][0]]\n",
    "                acc = []\n",
    "                # 添加账户\n",
    "                for account in uf.accounts[key]:\n",
    "                    acc.append(account[1])\n",
    "                    \n",
    "                res.append(usr + sorted(acc))\n",
    "                \n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self):\n",
    "        self.father = {}\n",
    "        # 根节点所在集合的所有账户\n",
    "        self.accounts = {}\n",
    "        \n",
    "    def find(self,x):\n",
    "        if not self.father[x]: return x\n",
    "        \n",
    "        # 递归的路径压缩处理\n",
    "        self.father[x] = self.find(self.father[x])\n",
    "        \n",
    "        return self.father[x]\n",
    "    \n",
    "    def merge(self,x,y):\n",
    "        root_x,root_y = self.find(x),self.find(y)\n",
    "        \n",
    "        if root_x == root_y:\n",
    "            return\n",
    "        \n",
    "        # 按秩合并，更新根节点和所属的账户\n",
    "        if len(self.accounts[root_x]) > len(self.accounts[root_y]):\n",
    "            self.father[root_y] = root_x\n",
    "            self.accounts[root_x] += self.accounts[root_y]\n",
    "            del self.accounts[root_y]\n",
    "        else:\n",
    "            self.father[root_x] = root_y\n",
    "            self.accounts[root_y] += self.accounts[root_x]\n",
    "            del self.accounts[root_x]\n",
    "    \n",
    "    def add(self,x):\n",
    "        if x not in self.father:\n",
    "            self.father[x] = None\n",
    "            self.accounts[x] = [x]\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf = UnionFind()\n",
    "        for account in accounts:\n",
    "            # 找到姓名和主账户\n",
    "            name,master = account[0],account[1]\n",
    "            uf.add((name,master))\n",
    "            \n",
    "            # 和其余的账户一一合并\n",
    "            account = list(set(account[2:]))\n",
    "            for i in range(len(account)):\n",
    "                uf.add((name,account[i]))\n",
    "                uf.merge((name,master),(name,account[i]))\n",
    "        res = []\n",
    "        for key,value in uf.father.items():\n",
    "            # 是根节点\n",
    "            if not value:\n",
    "                # 添加user\n",
    "                usr = [uf.accounts[key][0][0]]\n",
    "                acc = []\n",
    "                # 添加账户\n",
    "                for account in uf.accounts[key]:\n",
    "                    acc.append(account[1])\n",
    "                    \n",
    "                res.append(usr + sorted(acc))\n",
    "                \n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict, deque\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        email_2_name = {}\n",
    "        adj_list = defaultdict(list)\n",
    "\n",
    "        for acc in accounts:\n",
    "            name, e0, rem = acc[0], acc[1], acc[2:]\n",
    "            email_2_name[e0] = name\n",
    "            for tmp in rem:\n",
    "                adj_list[e0].append(tmp)\n",
    "                adj_list[tmp].append(e0)\n",
    "                email_2_name[tmp] = name\n",
    "\n",
    "        visited = set()\n",
    "        queue = deque([])\n",
    "        res = []\n",
    "        # traverse each non-visited email\n",
    "        for email in email_2_name:\n",
    "            if email in visited:    continue\n",
    "            visited.add(email)\n",
    "            queue.append(email)\n",
    "\n",
    "            routes = []\n",
    "            while queue:\n",
    "                cur = queue.popleft()\n",
    "                routes.append(cur)\n",
    "                for nxt in adj_list[cur]:\n",
    "                    if nxt not in visited:\n",
    "                        queue.append(nxt)\n",
    "                        visited.add(nxt)\n",
    "\n",
    "            # push traversed route for connected emails\n",
    "            res.append([email_2_name[email]] + sorted(routes))\n",
    "        \n",
    "        return res\n",
    "\n",
    "        \n",
    "\n",
    "                \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self, n):\n",
    "        self.parents = [i for i in range(n)]\n",
    "\n",
    "    def union(self, account1, account2):\n",
    "        self.parents[self.find(account1)] = self.find(account2)\n",
    "    \n",
    "    def find(self, account):\n",
    "        if self.parents[account] != account:\n",
    "            self.parents[account] = self.find(self.parents[account])\n",
    "        return self.parents[account]\n",
    "            \n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        nameAccounts = {}\n",
    "        for account in accounts:\n",
    "            name = account[0]\n",
    "            if name not in nameAccounts:\n",
    "                nameAccounts[name] = []\n",
    "            nameAccounts[name].append(account)\n",
    "        \n",
    "        results = []\n",
    "        for name in nameAccounts:\n",
    "            curAccounts = nameAccounts[name]\n",
    "            accountIds = {}\n",
    "            for accountList in curAccounts:\n",
    "                for idx in range(1, len(accountList)):\n",
    "                    if accountList[idx] not in accountIds:\n",
    "                        accountIds[accountList[idx]] = len(accountIds)\n",
    "            \n",
    "            unionFind = UnionFind(len(accountIds))\n",
    "            for accountList in curAccounts:\n",
    "                firstAccount = accountList[1]\n",
    "                firstAccountId = accountIds[accountList[1]]\n",
    "                for idx in range(2, len(accountList)):\n",
    "                    accountId = accountIds[accountList[idx]]\n",
    "                    unionFind.union(firstAccountId, accountId)\n",
    "            \n",
    "            mergedAccounts = {}\n",
    "            for accountList in curAccounts:\n",
    "                for idx in range(1, len(accountList)):\n",
    "                    accountId = accountIds[accountList[idx]]\n",
    "                    tmpId = unionFind.find(accountId)\n",
    "                    if tmpId not in mergedAccounts:\n",
    "                        mergedAccounts[tmpId] = set()\n",
    "                    mergedAccounts[tmpId].add(accountList[idx])\n",
    "            for key in mergedAccounts:\n",
    "                mergedAccounts[key] = list(mergedAccounts[key])\n",
    "                mergedAccounts[key].sort()\n",
    "                results.append([name] + mergedAccounts[key])\n",
    "        \n",
    "        return results\n",
    "\n",
    "\n",
    "            \n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class UnionFind:\n",
    "    def __init__(self):\n",
    "        self.parent = {}\n",
    "    def union(self, index1: int, index2: int):\n",
    "        self.parent[self.find(index2)] = self.find(index1)\n",
    "    def find(self, index: int) -> int:\n",
    "        self.parent.setdefault(index,index)\n",
    "        if self.parent[index] != index:\n",
    "            self.parent[index] = self.find(self.parent[index])\n",
    "        return self.parent[index]\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        emailToName = dict()\n",
    "        for account in accounts:\n",
    "            for email in account[1:]:\n",
    "                emailToName[email] = account[0]\n",
    "        uf = UnionFind()\n",
    "        for account in accounts:\n",
    "            for email in account[2:]:\n",
    "                uf.union(account[1], email)\n",
    "        indexToEmails = collections.defaultdict(set)\n",
    "        for account in accounts:\n",
    "            for email in account[1:]:\n",
    "                f = uf.find(email)\n",
    "                indexToEmails[f].add(email)\n",
    "                # indexToEmails[f].add(f)\n",
    "        ans = list()\n",
    "        for k,v in indexToEmails.items():\n",
    "            ans.append([emailToName[k]] + sorted(v))\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict, deque\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        email_2_name = {}\n",
    "        adj_list = defaultdict(list)\n",
    "\n",
    "        for acc in accounts:\n",
    "            name, e0, rem = acc[0], acc[1], acc[2:]\n",
    "            email_2_name[e0] = name\n",
    "            for tmp in rem:\n",
    "                adj_list[e0].append(tmp)\n",
    "                adj_list[tmp].append(e0)\n",
    "                email_2_name[tmp] = name\n",
    "\n",
    "        visited = set()\n",
    "        queue = deque([])\n",
    "        res = []\n",
    "        for email in email_2_name:\n",
    "            if email in visited:    continue\n",
    "            visited.add(email)\n",
    "            queue.append(email)\n",
    "\n",
    "            routes = []\n",
    "            while queue:\n",
    "                cur = queue.popleft()\n",
    "                routes.append(cur)\n",
    "                for nxt in adj_list[cur]:\n",
    "                    if nxt not in visited:\n",
    "                        queue.append(nxt)\n",
    "                        visited.add(nxt)\n",
    "\n",
    "            res.append([email_2_name[email]] + sorted(routes))\n",
    "        \n",
    "        return res\n",
    "\n",
    "        \n",
    "\n",
    "                \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        # 构建无向图，每个邮箱为一个节点，同一个账户的邮箱全部相连\n",
    "        # 有多少连通分量，就有多少独立的账户\n",
    "        # 该字典，键为一个邮箱，值为与其相连的所有邮箱\n",
    "        graph = collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            master = account[1]\n",
    "            for email in list(set(account[2:])):\n",
    "                graph[master].append(email)\n",
    "                graph[email].append(master)\n",
    "\n",
    "        res = [] # 最终的输出结果\n",
    "        visited = set() # 标记集合\n",
    "\n",
    "        for account in accounts:\n",
    "            emails = [] # 存储该账户的所有邮箱\n",
    "            # 深度优先遍历\n",
    "            self.dfs(account[1],graph,visited,emails)\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        return res\n",
    "\n",
    "    # 深度优先遍历\n",
    "    def dfs(self,email,graph,visited,emails):\n",
    "        # 访问过，不在添加直接结束\n",
    "        if email in visited:\n",
    "            return \n",
    "        visited.add(email) # 标记访问\n",
    "        emails.append(email) # 添加\n",
    "        for neighbor in graph[email]:\n",
    "            self.dfs(neighbor,graph,visited,emails)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def build_graph(self,accounts):\n",
    "        \"\"\"\n",
    "        建图\n",
    "        \"\"\"\n",
    "        graph = collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            name = account[1]\n",
    "            # 对剩余账户做一个去重\n",
    "            for email in account[2:]:\n",
    "                graph[name].append(email)\n",
    "                graph[email].append(name)\n",
    "        \n",
    "        return graph\n",
    "    \n",
    "    def dfs(self,email,graph,visited,emails):\n",
    "        # 已经访问过的就剪枝\n",
    "        if email in visited:\n",
    "            return \n",
    "        visited.add(email)\n",
    "        emails.append(email)\n",
    "        # 对邻居节点继续深搜\n",
    "        for neighbor in graph[email]:\n",
    "            self.dfs(neighbor,graph,visited,emails)\n",
    "    \n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        graph = self.build_graph(accounts)\n",
    "\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            emails = []\n",
    "            self.dfs(account[1],graph,visited,emails) # 每一条记录的第一个邮箱为起始点\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def build_graph(self,accounts):\n",
    "        \"\"\"\n",
    "        建图\n",
    "        \"\"\"\n",
    "        graph = collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            master = account[1]\n",
    "            # 对剩余账户做一个去重\n",
    "            for email in list(set(account[2:])):\n",
    "                graph[master].append(email)\n",
    "                graph[email].append(master)\n",
    "        \n",
    "        return graph\n",
    "    \n",
    "    def dfs(self,email,graph,visited,emails):\n",
    "        \"\"\"\n",
    "        深搜遍历\n",
    "        \"\"\"\n",
    "        # 已经访问过的就剪枝\n",
    "        if email in visited:\n",
    "            return \n",
    "        \n",
    "        visited.add(email)\n",
    "        emails.append(email)\n",
    "        \n",
    "        # 对邻居节点继续深搜\n",
    "        for neighbor in graph[email]:\n",
    "            self.dfs(neighbor,graph,visited,emails)\n",
    "    \n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        graph = self.build_graph(accounts)\n",
    "\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            emails = []\n",
    "            self.dfs(account[1],graph,visited,emails)\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        \n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        # 构建无向图，每个邮箱为一个节点，同一个账户的邮箱全部相连\n",
    "        # 有多少连通分量，就有多少独立的账户\n",
    "        # 该字典，键为一个邮箱，值为与其相连的所有邮箱\n",
    "        graph = collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            master = account[1]\n",
    "            for email in list(set(account[2:])):\n",
    "                graph[master].append(email)\n",
    "                graph[email].append(master)\n",
    "\n",
    "        res = [] # 最终的输出结果\n",
    "        visited = set() # 标记集合\n",
    "\n",
    "        for account in accounts:\n",
    "            emails = [] # 存储该账户的所有邮箱\n",
    "            # 深度优先遍历\n",
    "            self.dfs(account[1],graph,visited,emails)\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        return res\n",
    "\n",
    "    # 深度优先遍历\n",
    "    def dfs(self,email,graph,visited,emails):\n",
    "        # 访问过，不在添加直接结束\n",
    "        if email in visited:\n",
    "            return \n",
    "        visited.add(email) # 标记访问\n",
    "        emails.append(email) # 添加\n",
    "        for neighbor in graph[email]:\n",
    "            self.dfs(neighbor,graph,visited,emails)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "\n",
    "        graph = collections.defaultdict(list)\n",
    "        for acc in accounts:\n",
    "            holder = acc[1]\n",
    "            for email in list(set(acc[2:])):\n",
    "                graph[holder].append(email)\n",
    "                graph[email].append(holder)\n",
    "\n",
    "\n",
    "        def dfs(email,graph,visited,emails):\n",
    "            if email in visited:\n",
    "                return\n",
    "\n",
    "            visited.add(email)\n",
    "            emails.append(email)\n",
    "\n",
    "            for neighbor in graph[email]:\n",
    "                dfs(neighbor,graph,visited,emails)\n",
    "        \n",
    "        ans = []\n",
    "        visited = set()\n",
    "        for acc in accounts:\n",
    "            emails = []\n",
    "            dfs(acc[1],graph,visited,emails)\n",
    "            if emails:\n",
    "                ans.append([acc[0]] + sorted(emails))\n",
    "        \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        class UnionFind:\n",
    "            def __init__(self, n):\n",
    "                self.parents = dict()\n",
    "                for i in range(n):\n",
    "                    self.parents[i] = i\n",
    "\n",
    "            def find(self, x):\n",
    "                if self.parents[x]!=x:\n",
    "                    return self.find(self.parents[x])\n",
    "                else:\n",
    "                    return x\n",
    "\n",
    "            def union(self, a, b):\n",
    "                self.parents[self.find(a)] = self.find(b)\n",
    "        \n",
    "        from collections import defaultdict\n",
    "        rela = defaultdict(list)\n",
    "        for i in range(len(accounts)):\n",
    "            for email in accounts[i][1:]:\n",
    "                rela[email].append(i)\n",
    "        \n",
    "        uf = UnionFind(len(accounts))\n",
    "        for r in rela:\n",
    "            if len(rela[r])>1:\n",
    "                for node in rela[r][1:]:\n",
    "                    uf.union(rela[r][0], node)\n",
    "        print(uf.parents)\n",
    "\n",
    "        index_emails = defaultdict(set)\n",
    "        for i in range(len(accounts)):\n",
    "            for email in accounts[i][1:]:\n",
    "                index_emails[uf.find(i)].add(email)\n",
    "        print(index_emails)\n",
    "\n",
    "        ans = []\n",
    "        for i in index_emails:\n",
    "            curr = [accounts[i][0]] + sorted(index_emails[i])\n",
    "            ans.append(curr)\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "\n",
    "\n",
    "        def isSameaccount(a1, a2):\n",
    "            if a1[0] != a2[0]: return False\n",
    "            for i in range(1, len(a1)):\n",
    "                for j in range(1, len(a2)):\n",
    "                    if a1[i] == a2[j]: return True\n",
    "            return False\n",
    "        \n",
    "        def buildGraph(accounts):\n",
    "            n = len(accounts)\n",
    "            graph = [[] for _ in range(n)]\n",
    "\n",
    "            for i in range(n):\n",
    "                for j in range(i+1, n):\n",
    "                    if isSameaccount(accounts[i], accounts[j]):\n",
    "                        graph[i].append(j)\n",
    "                        graph[j].append(i)\n",
    "            return graph\n",
    "\n",
    "        graph = buildGraph(accounts)\n",
    "        \n",
    "        def dfs(i, seen, graph, curr):\n",
    "            if seen[i]: return\n",
    "            seen[i] = 1\n",
    "            for email in accounts[i][1:]:\n",
    "                curr.add(email)\n",
    "            \n",
    "            for nei in graph[i]:\n",
    "                dfs(nei, seen, graph, curr)\n",
    "        \n",
    "        ans = []\n",
    "        seen = [0]*len(accounts)\n",
    "        for i in range(len(accounts)):\n",
    "            if seen[i]: continue\n",
    "            curr = set()\n",
    "            dfs(i, seen, graph, curr)\n",
    "            ans.append([accounts[i][0]]+sorted(list(curr)))\n",
    "        \n",
    "        return ans\n",
    "\n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "\n",
    "        emailToName = {}\n",
    "        graphs = defaultdict(set)\n",
    "\n",
    "        for acct in accounts:\n",
    "            name = acct[0]\n",
    "            for email in acct[1:]:\n",
    "                graphs[acct[1]].add(email)\n",
    "                graphs[email].add(acct[1])\n",
    "                emailToName[email] = name\n",
    "        \n",
    "        seen = set()\n",
    "        res = []\n",
    "        for email in graphs:\n",
    "            if email not in seen:\n",
    "                seen.add(email)\n",
    "                stack = [email]\n",
    "                comp = []\n",
    "                while stack:\n",
    "                    e = stack.pop(0)\n",
    "                    comp.append(e)\n",
    "                    for g in graphs[e]:\n",
    "                        if g not in seen:\n",
    "                            seen.add(g)\n",
    "                            stack.append(g)\n",
    "                res.append([emailToName[email]] + sorted(comp))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        class UnionFind():\n",
    "            def __init__(self, n):\n",
    "                self.parents = []\n",
    "                for i in range(n):\n",
    "                    self.parents.append(i)\n",
    "            \n",
    "            def union(self, a, b):\n",
    "                root_a = self.find(a)\n",
    "                root_b = self.find(b)\n",
    "\n",
    "                self.parents[root_b] = root_a\n",
    "            \n",
    "            def find(self, x):\n",
    "                while self.parents[x] != x:\n",
    "                    x = self.parents[x]\n",
    "                \n",
    "                return x\n",
    "\n",
    "        from collections import defaultdict\n",
    "\n",
    "        email_index_dict = defaultdict(set)\n",
    "\n",
    "        uf = UnionFind(len(accounts))\n",
    "\n",
    "        for index_a in range(len(accounts)):\n",
    "            for email in accounts[index_a][1:]:\n",
    "                for index_b in email_index_dict[email]:\n",
    "                    uf.union(index_a, index_b)\n",
    "                email_index_dict[email].add(index_a)\n",
    "        \n",
    "        index_email_dict = defaultdict(set)\n",
    "\n",
    "        for email in email_index_dict.keys():\n",
    "            index = list(email_index_dict[email])[0]\n",
    "            root_index = uf.find(index)\n",
    "\n",
    "            index_email_dict[root_index].add(email)\n",
    "        \n",
    "\n",
    "        ans = []\n",
    "\n",
    "        for index, emails in index_email_dict.items():\n",
    "            name = accounts[index][0]\n",
    "            ans.append([name]+sorted(emails))\n",
    "        \n",
    "\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        if accounts==[]:return []\n",
    "        dic={}#dic[邮箱]=accounts中的编号\n",
    "        for i in range(len(accounts)):\n",
    "            for j in range(1,len(accounts[i])):\n",
    "                if accounts[i][j] not in dic:\n",
    "                    dic[accounts[i][j]]={i}\n",
    "                else:\n",
    "                    dic[accounts[i][j]].add(i)\n",
    "        zgd=set()\n",
    "        def dfs(idx):\n",
    "            if idx in zgd:return\n",
    "            zgd.add(idx)\n",
    "            for temp in accounts[idx][1:]:#邮箱\n",
    "                data.add(temp)\n",
    "                for kkk in dic[temp]:#邮箱下有的编号\n",
    "                    dfs(kkk)\n",
    "            return\n",
    "        op=[]\n",
    "        for i in range(len(accounts)):\n",
    "            if i not in zgd:\n",
    "                data=set()\n",
    "                dfs(i)\n",
    "                temp=list(data)\n",
    "                temp.sort()\n",
    "                op.append([accounts[i][0]]+temp)\n",
    "        return op"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        email2Name = dict()\n",
    "        edges = defaultdict(list)\n",
    "\n",
    "        for account in accounts:\n",
    "            for i in range(1, len(account)):\n",
    "                if i + 1 < len(account):\n",
    "                    edges[account[i]].append(account[i + 1])\n",
    "                    edges[account[i + 1]].append(account[i])\n",
    "                email2Name[account[i]] = account[0]\n",
    "\n",
    "        print(edges)\n",
    "        print(email2Name)\n",
    "        res = []\n",
    "        visited = set()\n",
    "\n",
    "        for email in email2Name:\n",
    "            if email in visited:\n",
    "                continue\n",
    "            curGroup = []\n",
    "            self.dfs(email, visited, curGroup, edges)\n",
    "            g = sorted(curGroup)\n",
    "            g.insert(0, email2Name[email])\n",
    "            res.append(g)\n",
    "\n",
    "        return res\n",
    "    def dfs(self, cur, visited, curGroup, edges):\n",
    "        if cur in visited:\n",
    "            return \n",
    "        visited.add(cur)\n",
    "        curGroup.append(cur)\n",
    "        for next_node in edges[cur]:\n",
    "            self.dfs(next_node, visited, curGroup, edges)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "  def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "    r = defaultdict(lambda:[])\n",
    "    for a in accounts:\n",
    "      n = a[0]\n",
    "      r[n].append(a[1:])\n",
    "    def grp(aEg):\n",
    "      dat = defaultdict(lambda:[])\n",
    "      r = defaultdict(lambda:False)\n",
    "      all = []\n",
    "      for g in aEg:\n",
    "        l = len(g)\n",
    "        for i in range(l):\n",
    "          a = g[i]\n",
    "          for j in range(i, l):\n",
    "            b = g[j]\n",
    "            dat[a].append(b)\n",
    "            dat[b].append(a)\n",
    "      \n",
    "      def div(aE):\n",
    "        r[aE] = True\n",
    "        ret = {aE}\n",
    "        q = [aE]\n",
    "        while len(q) > 0:\n",
    "          e = q.pop(0)\n",
    "          for re in dat[e]:\n",
    "            if False == r[re]:\n",
    "              r[re] = True\n",
    "              ret.add(re)\n",
    "              q.append(re)\n",
    "        lr = list(ret)\n",
    "        lr.sort()\n",
    "        return lr\n",
    "\n",
    "      ret = []\n",
    "      for g in aEg:\n",
    "        for e in g:\n",
    "          if not r[e]:\n",
    "            ret.append(div(e))\n",
    "      return ret\n",
    "\n",
    "    ret = []\n",
    "    for n, e in r.items():\n",
    "      if len(e) > 1:\n",
    "        for g in grp(e):\n",
    "          ret.append([n] + g)\n",
    "      else:\n",
    "        se = set(e[0])\n",
    "        le = list(se)\n",
    "        le.sort()\n",
    "        ret.append([n] + le)\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "  def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "    r = defaultdict(lambda:[])\n",
    "    for a in accounts:\n",
    "      n = a[0]\n",
    "      r[n].append(a[1:])\n",
    "    def grp(aEg):\n",
    "      dat = defaultdict(lambda:[])\n",
    "      r = defaultdict(lambda:False)\n",
    "      all = []\n",
    "      for g in aEg:\n",
    "        l = len(g)\n",
    "        for i in range(l):\n",
    "          a = g[i]\n",
    "          for j in range(i, l):\n",
    "            b = g[j]\n",
    "            dat[a].append(b)\n",
    "            dat[b].append(a)\n",
    "      \n",
    "      def div(aE):\n",
    "        r[aE] = True\n",
    "        ret = {aE}\n",
    "        q = [aE]\n",
    "        while len(q) > 0:\n",
    "          e = q.pop(0)\n",
    "          for re in dat[e]:\n",
    "            if False == r[re]:\n",
    "              r[re] = True\n",
    "              ret.add(re)\n",
    "              q.append(re)\n",
    "        lr = list(ret)\n",
    "        lr.sort()\n",
    "        return lr\n",
    "\n",
    "      ret = []\n",
    "      for g in aEg:\n",
    "        for e in g:\n",
    "          if not r[e]:\n",
    "            ret.append(div(e))\n",
    "      return ret\n",
    "\n",
    "    ret = []\n",
    "    for n, e in r.items():\n",
    "      if len(e) > 1:\n",
    "        for g in grp(e):\n",
    "          ret.append([n] + g)\n",
    "      else:\n",
    "        se = set(e[0])\n",
    "        le = list(se)\n",
    "        le.sort()\n",
    "        ret.append([n] + le)\n",
    "    return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:   \n",
    "        ## 广度 优先 搜索 (BFS)\n",
    "                ## 建图\n",
    "        graph = collections.defaultdict(set)\n",
    "        for account in accounts:\n",
    "            email0 = account[1]\n",
    "            for email in account[2:]:\n",
    "                graph[email0].add(email)  ## 这些 email  对应 同一个人， 等效于 可连通\n",
    "                graph[email].add(email0)\n",
    "\n",
    "        res = []\n",
    "        visited = set()\n",
    "\n",
    "        for account in accounts: \n",
    "            \n",
    "            q = collections.deque([account[1]])\n",
    "            emails = []\n",
    "            while q:\n",
    "                email0 = q.popleft()    \n",
    "                if email0 not in visited:  ## \n",
    "                    visited.add(email0)\n",
    "                    emails.append(email0)\n",
    "                    for neighbor in graph[email0]:  ## 建好图 后， 同一个人的 所有的email 都在这里， 此外 每一个account 里的email 都是 同一 人的。 都要 加上\n",
    "                        q.append(neighbor)\n",
    "                    \n",
    "            if emails: \n",
    "                res.append([account[0]] + sorted(emails))\n",
    "\n",
    "        return res \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def merge_sort(self, left, right):\n",
    "        res = []\n",
    "        i, j = 0, 0\n",
    "        while i < len(left) and j < len(right):\n",
    "            if left[i] < right[j]:\n",
    "                res.append(left[i])\n",
    "                i += 1\n",
    "            elif left[i] > right[j]:\n",
    "                res.append(right[j])\n",
    "                j += 1\n",
    "            else:\n",
    "                res.append(left[i])\n",
    "                i += 1\n",
    "                j += 1\n",
    "        res += left[i:]\n",
    "        res += right[j:]\n",
    "        return res\n",
    "\n",
    "    def accountsMerge_(self, accounts: List[List[str]]):\n",
    "        if len(accounts) == 1:\n",
    "            res = [accounts[0][0:1] + sorted(set(accounts[0][1:]))]\n",
    "            email_ids = dict((email, 0) for email in res[0][1:])\n",
    "            return res, email_ids\n",
    "        else:\n",
    "            left_res, left_email_ids =  self.accountsMerge_(accounts[:-1])\n",
    "            last_account = accounts[-1]\n",
    "            last_account = last_account[0:1] + sorted(set(last_account[1:]))\n",
    "            to_be_merge_ids = set()\n",
    "            for email in last_account[1:]:\n",
    "                if email in left_email_ids:\n",
    "                    to_be_merge_ids.add(left_email_ids[email])\n",
    "            if not to_be_merge_ids:\n",
    "                for email in last_account[1:]:\n",
    "                    left_email_ids[email] = len(left_res)\n",
    "                left_res.append(last_account)\n",
    "                return left_res, left_email_ids\n",
    "            else:\n",
    "                res = []\n",
    "                buf = []\n",
    "                for i in range(len(left_res)):\n",
    "                    if i in to_be_merge_ids:\n",
    "                        buf = self.merge_sort(buf, left_res[i][1:])\n",
    "                    else:\n",
    "                        res.append(left_res[i])\n",
    "                buf = self.merge_sort(buf, last_account[1:])\n",
    "                res.append(last_account[0:1] + buf)\n",
    "                email_ids = {}\n",
    "                for i, row in enumerate(res):\n",
    "                    for email in row[1:]:\n",
    "                        email_ids[email] = i\n",
    "                return res, email_ids\n",
    "\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        res, _ = self.accountsMerge_(accounts)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class UnionFind:\n",
    "\n",
    "    def __init__(self, accounts):\n",
    "        n = len(accounts)\n",
    "        self.parent = [i for i in range(n)]\n",
    "        self.size = [1] * n\n",
    "        self.emails = [None] * n\n",
    "        for i, acc in enumerate(accounts):\n",
    "            self.emails[i] = set(acc[1:])\n",
    "\n",
    "    def union(self, x, y):\n",
    "        px, py = self.find(x), self.find(y)\n",
    "        if px == py:\n",
    "            return\n",
    "        if self.size[px] > self.size[py]:\n",
    "            px, py = py, px\n",
    "        self.parent[px] = py\n",
    "        self.size[py] += self.size[px]\n",
    "        for email in self.emails[px]:\n",
    "            self.emails[py].add(email)\n",
    "\n",
    "    def find(self, x):\n",
    "        if self.parent[x] != x:\n",
    "            self.parent[x] = self.find(self.parent[x])\n",
    "        return self.parent[x]\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        n = len(accounts)\n",
    "        uf = UnionFind(accounts)\n",
    "        email_idx = collections.defaultdict(list)\n",
    "        for cur, acc in enumerate(accounts):\n",
    "            for email in acc[1:]:\n",
    "                for pre in email_idx[email]:\n",
    "                    uf.union(pre, cur)\n",
    "                email_idx[email].append(cur)\n",
    "\n",
    "        ans = []\n",
    "        seen = set()\n",
    "        for i in range(n):\n",
    "            pi = uf.find(i)\n",
    "            if pi not in seen:\n",
    "                seen.add(pi)\n",
    "                ans.append(accounts[i][:1] + sorted(uf.emails[pi]))\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, a: List[List[str]]) -> List[List[str]]:\n",
    "        g = defaultdict(set)\n",
    "        for j in range(len(a)):\n",
    "            b = a[j]\n",
    "            for k in b[1:]:\n",
    "                g[j].add(k)\n",
    "                g[k].add(j) \n",
    "        v = set()\n",
    "        def bfs(x):\n",
    "            if x in v:\n",
    "                return \n",
    "            ans = [x]\n",
    "            v.add(x)\n",
    "            s = [x]\n",
    "            while s:\n",
    "                tmp = []\n",
    "                for j in s:\n",
    "                    for k in g[j]:\n",
    "                        if k not in v:\n",
    "                            v.add(k)\n",
    "                            tmp.append(k)\n",
    "                s = tmp \n",
    "                ans += tmp\n",
    "            return ans \n",
    "        ans = []\n",
    "        for j in g:\n",
    "            if j not in v:\n",
    "                tmp = bfs(j)\n",
    "                b = [k for k in tmp if type(k)==int]\n",
    "                c = [k for k in tmp if type(k)!=int]\n",
    "                b = [a[b[0]][0]]\n",
    "                c.sort()\n",
    "                b += c \n",
    "                \n",
    "                ans.append(b)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:   \n",
    "        ## 广度 优先 搜索 (BFS)\n",
    "                ## 建图\n",
    "        graph = collections.defaultdict(set)\n",
    "        for account in accounts:\n",
    "            email0 = account[1]\n",
    "            for email in account[2:]:\n",
    "                graph[email0].add(email)  ## 这些 email  对应 同一个人， 等效于 可连通\n",
    "                graph[email].add(email0)\n",
    "\n",
    "        res = []\n",
    "        visited = set()\n",
    "\n",
    "        for account in accounts: \n",
    "            \n",
    "            q = collections.deque([account[1]])\n",
    "            emails = []\n",
    "            while q:\n",
    "                email0 = q.popleft()    \n",
    "                if email0 not in visited:  ## \n",
    "                    visited.add(email0)\n",
    "                    emails.append(email0)\n",
    "                    for neighbor in graph[email0]:  ## 建好图 后， 同一个人的 所有的email 都在这里， 此外 每一个account 里的email 都是 同一 人的。 都要 加上\n",
    "                        q.append(neighbor)\n",
    "                    \n",
    "            if emails: \n",
    "                res.append([account[0]] + sorted(emails))\n",
    "\n",
    "        return res \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, a: List[List[str]]) -> List[List[str]]:\n",
    "        g = defaultdict(set)\n",
    "        for j in range(len(a)):\n",
    "            b = a[j]\n",
    "            for k in b[1:]:\n",
    "                g[j].add(k)\n",
    "                g[k].add(j) \n",
    "        v = set()\n",
    "        def bfs(x):\n",
    "            if x in v:\n",
    "                return \n",
    "            ans = [x]\n",
    "            v.add(x)\n",
    "            s = [x]\n",
    "            while s:\n",
    "                tmp = []\n",
    "                for j in s:\n",
    "                    for k in g[j]:\n",
    "                        if k not in v:\n",
    "                            v.add(k)\n",
    "                            tmp.append(k)\n",
    "                s = tmp \n",
    "                ans += tmp\n",
    "            return ans \n",
    "        ans = []\n",
    "        for j in g:\n",
    "            if j not in v:\n",
    "                tmp = bfs(j)\n",
    "                b = [k for k in tmp if type(k)==int]\n",
    "                c = [k for k in tmp if type(k)!=int]\n",
    "                b = [a[b[0]][0]]\n",
    "                c.sort()\n",
    "                b += c \n",
    "                \n",
    "                ans.append(b)\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        # 建立无向图\n",
    "        graph = collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            k = account[1]\n",
    "            for email in list(set(account[2:])):\n",
    "                graph[k].append(email)\n",
    "                graph[email].append(k)\n",
    "            \n",
    "        # dfs\n",
    "        def dfs(email,visit,cur_re):\n",
    "            if email in visit:\n",
    "                return\n",
    "            visit.add(email)\n",
    "            cur_re.append(email)\n",
    "            for i in graph[email]:\n",
    "                dfs(i,visit,cur_re)\n",
    "        \n",
    "        # solution\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            cur_re = []\n",
    "            dfs(account[1],visited,cur_re)\n",
    "            if cur_re:\n",
    "                res.append([account[0]] + sorted(cur_re))\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        dict = defaultdict(list)\n",
    "        visited = [False] * len(accounts)\n",
    "        res = []\n",
    "\n",
    "        for i in range(len(accounts)):\n",
    "            for j in range(1, len(accounts[i])):\n",
    "                email = accounts[i][j]\n",
    "                dict[email].append(i)\n",
    "\n",
    "        def dfs(i, emails):\n",
    "            if visited[i]:\n",
    "                return \n",
    "            visited[i] = True\n",
    "            for j in range(1, len(accounts[i])):\n",
    "                email = accounts[i][j]\n",
    "                emails.add(email)\n",
    "                for neighbor in dict[email]:\n",
    "                    dfs(neighbor, emails)\n",
    "        \n",
    "        for i in range(len(accounts)):\n",
    "            if visited[i]:\n",
    "                continue\n",
    "            name, emails = accounts[i][0], set()\n",
    "            dfs(i, emails)\n",
    "            res.append([name] + sorted(emails))\n",
    "        return res \n",
    "                \n",
    "        \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: list[list[str]]) -> list[list[str]]:\n",
    "        dic=collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            main=account[1]\n",
    "            for email in account[2:]:\n",
    "                dic[main].append(email)\n",
    "                dic[email].append(main)\n",
    "        def dfs(email,ans,visited):\n",
    "            if email in visited:\n",
    "                return \n",
    "            visited.add(email)\n",
    "            ans.append(email)\n",
    "            for neigh in dic[email]:\n",
    "                dfs(neigh,ans,visited)\n",
    "        ans=[]\n",
    "        visited=set()\n",
    "        for account in accounts:\n",
    "            temp=[]\n",
    "            if account[1] not in visited:\n",
    "                dfs(account[1],temp,visited)\n",
    "                ans.append([account[0]]+sorted(temp))\n",
    "        return ans \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "from typing import List\n",
    "\n",
    "\n",
    "# class Solution:\n",
    "#     def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        \n",
    "\n",
    "# 建图，我们可以忽略姓名，直接把关联的账户连接起来即可\n",
    "# 对每一个 account 子数组的第一个邮箱进行深度优先搜索，子数组的姓名+得到的账户组（也要再排个序） 就是这个人对应的答案\n",
    "\n",
    "# dfs\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        def build_graph(accounts):\n",
    "            graph = collections.defaultdict(set)\n",
    "            for account in accounts:\n",
    "                first = account[1]\n",
    "                for email in account[2:]:\n",
    "                    graph[first].add(email)\n",
    "                    graph[email].add(first)\n",
    "            return graph\n",
    "\n",
    "        def dfs(email, graph, visited):\n",
    "            if email in visited:\n",
    "                return []\n",
    "            visited.add(email)\n",
    "            emails = [email]\n",
    "\n",
    "            for neighbor in graph[email]:\n",
    "                emails += dfs(neighbor, graph, visited)\n",
    "\n",
    "            return emails\n",
    "\n",
    "        graph = build_graph(accounts)\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            emails = dfs(account[1], graph, visited)\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        return res\n",
    "\n",
    "# 直接暴力地把 (姓名，邮箱) 当作并查集字典中的 key，再额外维护一个字典，以每个集合的根节点作为 key，存储每个集合中所有的 (姓名，邮箱)。\n",
    "# 每次合并集合的时候除了更新根节点外，还要更新根节点对应的 (姓名，邮箱)\n",
    "# 最后添加答案的时候别忘了对这个人的所有邮箱排序。\n",
    "\n",
    "# 并查集\n",
    "# class UnionFind:\n",
    "#     def __init__(self, n) -> None:\n",
    "#         self.parent = list(range(n + 1))\n",
    "#         # self.parent = collections.defaultdict()\n",
    "\n",
    "#     def find(self, x):\n",
    "#         if self.parent[x] != x:\n",
    "#             self.parent[x] = self.find(self.parent[x])\n",
    "#         return self.parent[x]\n",
    "\n",
    "#     def union(self, x, y):\n",
    "#         x = self.find(x)\n",
    "#         y = self.find(y)\n",
    "#         self.parent[x] = y\n",
    "\n",
    "\n",
    "# class Solution:\n",
    "#     def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "#         n = len(accounts)\n",
    "#         uf = UnionFind(n + 1)\n",
    "#         lookup = {}\n",
    "#         for id, account in enumerate(accounts):\n",
    "#             # name = account[0]\n",
    "#             emails = account[1:]\n",
    "#             for email in emails:\n",
    "#                 if email in lookup:\n",
    "#                     uf.union(id, lookup[email])\n",
    "#                 else:\n",
    "#                     lookup[email] = id\n",
    "\n",
    "#         joinSet = collections.defaultdict(set)\n",
    "#         for i in range(n):\n",
    "#             id = uf.find(i)\n",
    "#             for email in accounts[i][1:]:\n",
    "#                 joinSet[id].add(email)\n",
    "\n",
    "#         res = []\n",
    "#         for id, emails in joinSet.items():\n",
    "#             list(emails).sort()\n",
    "#             res.append([accounts[id][0]] + sorted(list(emails)))\n",
    "#         return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        # dfs\n",
    "        # 建图，我们可以忽略姓名，直接把关联的账户连接起来即可\n",
    "        # 对每一个 account 子数组的第一个邮箱进行深度优先搜索，子数组的姓名+得到的账户组（也要再排个序） 就是这个人对应的答案\n",
    "        def build_graph():\n",
    "            graph = defaultdict(list)\n",
    "            for account in accounts:\n",
    "                master = account[1]\n",
    "                for email in set(account[2:]):\n",
    "                    graph[master].append(email)\n",
    "                    graph[email].append(master)\n",
    "            return graph\n",
    "\n",
    "        def dfs(email, visited, emails):\n",
    "            if email in visited:\n",
    "                return\n",
    "            visited.add(email)\n",
    "            emails.append(email)\n",
    "            for nex in graph[email]:\n",
    "                dfs(nex, visited, emails)\n",
    "\n",
    "        graph = build_graph()\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            emails = []\n",
    "            dfs(account[1], visited, emails)\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        edges = dict()\n",
    "        for i, account_1 in enumerate(accounts):\n",
    "            edges[i] = []\n",
    "            for j in range(0, len(accounts)):\n",
    "                account_2  = accounts[j]\n",
    "                if account_1[0] == account_2[0] and i!=j:\n",
    "                    set_1 = set(account_1[1:])\n",
    "                    set_2 = set(account_2[1:])\n",
    "                    if (len(set_1|set_2) != len(set_1) + len(set_2)):\n",
    "                        edges[i].append(j)\n",
    "        visited = set()\n",
    "        def dfs(startIdx, tmp_):\n",
    "            for i in edges[startIdx]:\n",
    "                if i not in visited:\n",
    "                    visited.add(i)\n",
    "                    for candi in accounts[i]:\n",
    "                        if candi == accounts[startIdx][0]:\n",
    "                            pass\n",
    "                        else:\n",
    "                            tmp_.add(candi)\n",
    "                    dfs(i, tmp_)\n",
    "        res = []\n",
    "        for i in range(len(accounts)):\n",
    "            if i not in visited:\n",
    "                visited.add(i)\n",
    "                tmp = set(accounts[i][1:])\n",
    "                dfs(i, tmp)\n",
    "                res.append([accounts[i][0]] + sorted(list(tmp)))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "\n",
    "        # 深度优先遍历。\n",
    "        def dfs(cur_email, graph, email_list):\n",
    "            if cur_email in seen:     \n",
    "                return email_list\n",
    "\n",
    "            seen.add(cur_email)  \n",
    "            email_list.append(cur_email)  \n",
    "\n",
    "            # 对每个邻居， 都去深搜一下。\n",
    "            for neighbour in graph[cur_email]:\n",
    "                dfs(neighbour, graph, email_list)\n",
    "\n",
    "        # 构建无向图，每个邮箱为一个节点， 同一个账户的邮箱全部相连。\n",
    "        # 有多少联通分量，就有多少独立的账户\n",
    "        # 构建图，这部分应该是固定写法。\n",
    "\n",
    "        # g = {\"邮箱\"：[\"与此相连的所有邮箱\"...]}\n",
    "        g =  defaultdict(list)\n",
    "        for acc in accounts:\n",
    "            master = acc[1]  # 选取第一个邮箱作为键\n",
    "            for email in list(set(acc[2:])):\n",
    "                g[master].append(email)\n",
    "                g[email].append(master)  # 这里写的其实很巧妙。把数据很完整地统计进来。\n",
    "\n",
    "        ret = []\n",
    "        seen = set()\n",
    "\n",
    "        for acc in accounts:\n",
    "            cur_ret = []\n",
    "\n",
    "            # 这里就写为这样！ 让 dfs() 来改变 cur_ret 的值。\n",
    "            dfs(acc[1], g, cur_ret)\n",
    "\n",
    "            if cur_ret:\n",
    "                ret.append([acc[0]] + sorted(cur_ret))\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import collections\n",
    "from typing import List\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        def build_graph(accounts):\n",
    "            graph = collections.defaultdict(set)\n",
    "            for account in accounts:\n",
    "                first = account[1]\n",
    "                for email in account[2:]:\n",
    "                    graph[first].add(email)\n",
    "                    graph[email].add(first)\n",
    "            return graph\n",
    "\n",
    "        def dfs(email, graph, visited):\n",
    "            if email in visited:\n",
    "                return []\n",
    "            visited.add(email)\n",
    "            emails = [email]\n",
    "\n",
    "            for neighbor in graph[email]:\n",
    "                emails += dfs(neighbor, graph, visited)\n",
    "\n",
    "            return emails\n",
    "\n",
    "        graph = build_graph(accounts)\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            emails = dfs(account[1], graph, visited)\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        return res\n",
    "\n",
    "\n",
    "# 并查集\n",
    "# class UnionFind:\n",
    "#     def __init__(self, n) -> None:\n",
    "#         self.parent = list(range(n + 1))\n",
    "#         # self.parent = collections.defaultdict()\n",
    "\n",
    "#     def find(self, x):\n",
    "#         if self.parent[x] != x:\n",
    "#             self.parent[x] = self.find(self.parent[x])\n",
    "#         return self.parent[x]\n",
    "\n",
    "#     def union(self, x, y):\n",
    "#         x = self.find(x)\n",
    "#         y = self.find(y)\n",
    "#         self.parent[x] = y\n",
    "\n",
    "\n",
    "# class Solution:\n",
    "#     def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "#         n = len(accounts)\n",
    "#         uf = UnionFind(n + 1)\n",
    "#         lookup = {}\n",
    "#         for id, account in enumerate(accounts):\n",
    "#             # name = account[0]\n",
    "#             emails = account[1:]\n",
    "#             for email in emails:\n",
    "#                 if email in lookup:\n",
    "#                     uf.union(id, lookup[email])\n",
    "#                 else:\n",
    "#                     lookup[email] = id\n",
    "\n",
    "#         joinSet = collections.defaultdict(set)\n",
    "#         for i in range(n):\n",
    "#             id = uf.find(i)\n",
    "#             for email in accounts[i][1:]:\n",
    "#                 joinSet[id].add(email)\n",
    "\n",
    "#         res = []\n",
    "#         for id, emails in joinSet.items():\n",
    "#             list(emails).sort()\n",
    "#             res.append([accounts[id][0]] + sorted(list(emails)))\n",
    "#         return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        emails_accounts_map = defaultdict(list)\n",
    "        visited = [False] * len(accounts)\n",
    "        res = []\n",
    "\n",
    "        for i, account in enumerate(accounts):\n",
    "            for j in range(1, len(account)):\n",
    "                email = account[j]\n",
    "                emails_accounts_map[email].append(i)\n",
    "\n",
    "        def dfs(i, emails):\n",
    "            if visited[i]:\n",
    "                return\n",
    "            visited[i] = True\n",
    "            for j in range(1, len(accounts[i])):\n",
    "                email = accounts[i][j]\n",
    "                emails.add(email)\n",
    "                for neighbor in emails_accounts_map[email]:\n",
    "                    dfs(neighbor, emails)\n",
    "\n",
    "        for i, account in enumerate(accounts):\n",
    "            if visited[i]:\n",
    "                continue\n",
    "            name, emails = account[0], set()\n",
    "            dfs(i, emails)\n",
    "            res.append([name] + sorted(emails))\n",
    "        return res\n",
    "\n",
    "# leetcode submit region end(Prohibit modification and deletion)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        edges = dict()\n",
    "        for i, account_1 in enumerate(accounts):\n",
    "            edges[i] = []\n",
    "            for j in range(0, len(accounts)):\n",
    "                account_2  = accounts[j]\n",
    "                if account_1[0] == account_2[0] and i!=j:\n",
    "                    set_1 = set(account_1[1:])\n",
    "                    set_2 = set(account_2[1:])\n",
    "                    if (len(set_1|set_2) != len(set_1) + len(set_2)):\n",
    "                        edges[i].append(j)\n",
    "        visited = set()\n",
    "        def dfs(startIdx, tmp_):\n",
    "            for i in edges[startIdx]:\n",
    "                if i not in visited:\n",
    "                    visited.add(i)\n",
    "                    for candi in accounts[i]:\n",
    "                        if candi == accounts[startIdx][0]:\n",
    "                            pass\n",
    "                        else:\n",
    "                            tmp_.add(candi)\n",
    "                    dfs(i, tmp_)\n",
    "        res = []\n",
    "        for i in range(len(accounts)):\n",
    "            if i not in visited:\n",
    "                visited.add(i)\n",
    "                tmp = set(accounts[i][1:])\n",
    "                dfs(i, tmp)\n",
    "                res.append([accounts[i][0]] + sorted(list(tmp)))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        g=collections.defaultdict(list)\n",
    "        for a in accounts:\n",
    "            master = a[1]\n",
    "            for email in set(a[2:]):\n",
    "                g[master].append(email)\n",
    "                g[email].append(master)\n",
    "\n",
    "        def dfs(cur,vis,path):\n",
    "            if cur in vis:\n",
    "                return\n",
    "            vis.add(cur)\n",
    "            path.append(cur)\n",
    "            for n in g[cur]:\n",
    "                dfs(n,vis,path)\n",
    "        vis=set()\n",
    "        ans=[]\n",
    "        for a in accounts:\n",
    "            path=[]\n",
    "            dfs(a[1],vis,path)\n",
    "            if len(path)!=0:\n",
    "                ans.append([a[0]]+sorted(path))\n",
    "        return ans\n",
    "\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        dic = {}\n",
    "        ans = []\n",
    "        visited = set()\n",
    "        for i in range(len(accounts)):\n",
    "            for email in accounts[i][1:]:\n",
    "                if email in dic:\n",
    "                    dic[email].append(i)\n",
    "                else:\n",
    "                    dic[email] = [i]\n",
    "        for i in range(len(accounts)):\n",
    "            if i in visited:\n",
    "                continue\n",
    "            else:\n",
    "                ans.append([accounts[i][0]])\n",
    "                address = set()\n",
    "                dq = collections.deque([i])\n",
    "                while dq:\n",
    "                    index = dq.popleft()\n",
    "                    visited.add(index)\n",
    "                    for email in accounts[index][1:]:\n",
    "                        address.add(email)\n",
    "                        for line in dic[email]:\n",
    "                            if line not in visited:\n",
    "                                dq.append(line)\n",
    "                address = sorted(list(address))\n",
    "                ans[-1] += address\n",
    "        return ans\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "\n",
    "        fa = {}\n",
    "        acc = {}\n",
    "        \n",
    "        def find(a):\n",
    "            if fa[a] != a:\n",
    "                fa[a] = find(fa[a])\n",
    "\n",
    "            return fa[a]\n",
    "\n",
    "        def union(a, b):\n",
    "            pa, pb = find(a), find(b)\n",
    "            if pa == pb: return \n",
    "\n",
    "            fa[pa] = pb\n",
    "            acc[pb] += acc[pa]\n",
    "            del acc[pa]\n",
    "            return \n",
    "\n",
    "        def add(user, master):\n",
    "            if (user, master) not in fa: # only consider new nodes \n",
    "                acc[(user, master)] = [(user, master)]\n",
    "                fa[(user, master)] = (user, master)\n",
    "\n",
    "        \n",
    "        for account in accounts:\n",
    "            user, master = account[0], account[1]\n",
    "            add(user, master)\n",
    "\n",
    "            aa = list(set(account[2:]))\n",
    "            for i in range(len(aa)):\n",
    "                add(user, aa[i])\n",
    "                union((user, master), (user, aa[i]))\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        res = []\n",
    "        for root, val in fa.items():\n",
    "            if root == val: # consider only root nodes \n",
    "                user = acc[root][0][0]\n",
    "                tmp = []\n",
    "                for account in acc[root]:\n",
    "                    tmp.append(account[1])\n",
    "\n",
    "                res.append([user] + sorted(tmp))\n",
    "        return res\n",
    "\n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        \n",
    "        # child2master = {} # we create this so that we can union these accounts\n",
    "        master2person = {}\n",
    "\n",
    "        master2child = defaultdict(list)\n",
    "\n",
    "        for account in accounts:\n",
    "            name, master = account[0], account[1]\n",
    "            master2person[master] = person\n",
    "            if len(account) > 2: # has childern accounts\n",
    "                for i in range(2, len(account)):\n",
    "                    master2child[master].append(account[i])\n",
    "\n",
    "        # union\n",
    "\n",
    "\n",
    "        res = []\n",
    "        # create output\n",
    "        for master in child2master.values():\n",
    "            # for each unique master, find it's account person\n",
    "            person = master2person[master]\n",
    "            emails = master2child[master] + [master]\n",
    "            res.append([person] + emails)\n",
    "\n",
    "\n",
    "        return res\n",
    "                \n",
    "            \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#相同邮箱的账号一定属于同一个人，所以只能用邮箱来判断！\n",
    "#名称相同的账户不一定属于同一个人\n",
    "class DSU(object):\n",
    "    def __init__(self, n):\n",
    "        self.par = [i for i in range(n)]\n",
    "        self.rnk = [0] * n\n",
    "\n",
    "    def find(self, x):\n",
    "        if self.par[x] != x:\n",
    "            self.par[x] = self.find(self.par[x]) #状态压缩，递归继续找最根的位置，直接指向根节点\n",
    "        return self.par[x]\n",
    "\n",
    "    def union(self, x, y):\n",
    "        xr, yr = self.find(x), self.find(y)\n",
    "        if self.rnk[xr] < self.rnk[yr]: #希望平衡，把矮的接到高的上面去\n",
    "            self.par[xr] = yr\n",
    "        elif self.rnk[xr] > self.rnk[yr]:\n",
    "            self.par[yr] = xr\n",
    "        else:\n",
    "            self.par[yr] = xr\n",
    "            self.rnk[xr] += 1\n",
    "\n",
    "class Solution(object):\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        uf = DSU(len(accounts))\n",
    "        email_id = dict()  #{email: index} #下面是在更新这个dic的index\n",
    "        #根据email合并，但email又不是数字所以得用index合并\n",
    "        for index, account in enumerate(accounts):\n",
    "            for email in account[1:]:\n",
    "                if email in email_id: #如果出现过了，证明这两个email是属于同一个account id(即index)的那么就合并他们\n",
    "                    uf.union(email_id[email], index)\n",
    "                else:\n",
    "                    email_id[email] = index\n",
    "        print(email_id)            \n",
    "        id_email = collections.defaultdict(list)   #{index: [emailList]}\n",
    "        for email, index in email_id.items():\n",
    "            id_email[uf.find(index)].append(email)  # 注意这里id_email的key\n",
    "        print(id_email)  \n",
    "        return [[accounts[i][0]] + sorted(e) for i, e in id_email.items()]\n",
    "\n",
    "class Solution(object):\n",
    "    def accountsMerge(self, accounts):\n",
    "        from collections import defaultdict\n",
    "        visited_accounts = [False] * len(accounts)\n",
    "        emails_accounts_map = defaultdict(list)\n",
    "        res = []\n",
    "        # Build up the graph.\n",
    "        for i, account in enumerate(accounts):\n",
    "            for j in range(1, len(account)):\n",
    "                email = account[j]\n",
    "                emails_accounts_map[email].append(i)\n",
    "#因为是按照email来merge的，所以以email为key，index为value聚合到list里\n",
    "# emails_accounts_map = defaultdict(list,\n",
    "#            {'johnsmith@mail.com': [0, 2],\n",
    "#             'john00@mail.com': [0],\n",
    "#             'johnnybravo@mail.com': [1],\n",
    "#             'john_newyork@mail.com': [2],\n",
    "#             'mary@mail.com': [3]})\n",
    "        # DFS code for traversing accounts.\n",
    "        def dfs(i, emails):\n",
    "            if visited_accounts[i]: #注意\n",
    "                return\n",
    "            visited_accounts[i] = True  #访问过了这个账户就标记true\n",
    "            for j in range(1, len(accounts[i])):\n",
    "                email = accounts[i][j] #遍历每个email\n",
    "                emails.add(email)  #把email加进去\n",
    "                for neighbor in emails_accounts_map[email]: #再去查这个email对应的account\n",
    "                    dfs(neighbor, emails) #继续查别的\n",
    "        # Perform DFS for accounts and add to results.\n",
    "        for i, account in enumerate(accounts): #一个个来遍历\n",
    "            if visited_accounts[i]:  #如果visit过了，那么就不加\n",
    "                continue\n",
    "            name, emails = account[0], set()  \n",
    "            dfs(i, emails) #查第一个账户!\n",
    "            res.append([name] + sorted(emails)) #查完了之后append\n",
    "        return res\n",
    "#时间：快排最后Σnlogn（dominant了），其实前面都只有n的build graph\n",
    "#空间：Σn  存储n个account"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        edges = dict()\n",
    "        for i, account_1 in enumerate(accounts):\n",
    "            edges[i] = []\n",
    "            for j in range(0, len(accounts)):\n",
    "                account_2  = accounts[j]\n",
    "                if account_1[0] == account_2[0] and i!=j:\n",
    "                    set_1 = set(account_1[1:])\n",
    "                    set_2 = set(account_2[1:])\n",
    "                    if (len(set_1|set_2) != len(set_1) + len(set_2)):\n",
    "                        edges[i].append(j)\n",
    "        visited = set()\n",
    "        def dfs(startIdx, tmp_):\n",
    "            for i in edges[startIdx]:\n",
    "                if i not in visited:\n",
    "                    visited.add(i)\n",
    "                    for candi in accounts[i]:\n",
    "                        if candi == accounts[startIdx][0]:\n",
    "                            pass\n",
    "                        else:\n",
    "                            tmp_.add(candi)\n",
    "                    dfs(i, tmp_)\n",
    "        res = []\n",
    "        for i in range(len(accounts)):\n",
    "            if i not in visited:\n",
    "                visited.add(i)\n",
    "                tmp = set(accounts[i][1:])\n",
    "                dfs(i, tmp)\n",
    "                res.append([accounts[i][0]] + sorted(list(tmp)))\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        record = collections.defaultdict(list)\n",
    "        for item in accounts:\n",
    "            for emal in item[2:]:\n",
    "                record[item[1]].append(emal)\n",
    "                record[emal].append(item[1])\n",
    "        def dfs(email,tem):\n",
    "            if email in visit:\n",
    "                return\n",
    "            visit.add(email)\n",
    "            tem.append(email)\n",
    "            for e in record[email]:\n",
    "                dfs(e,tem)\n",
    "\n",
    "        visit = set()\n",
    "        res = []\n",
    "        for account in accounts:\n",
    "            tem = []\n",
    "            dfs(account[1],tem)\n",
    "            if tem:\n",
    "                res.append([account[0]] + sorted(tem))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        visited = set()\n",
    "        email2idx = collections.defaultdict(list)\n",
    "        res = []\n",
    "        def dfs(idx, emails):\n",
    "            if idx in visited:\n",
    "                return\n",
    "            visited.add(idx)\n",
    "            for email in accounts[idx][1:]:\n",
    "                emails.add(email)\n",
    "                for i in email2idx[email]:\n",
    "                    dfs(i, emails)\n",
    "\n",
    "        for idx, account in enumerate(accounts):\n",
    "            for email in account[1:]:\n",
    "                email2idx[email].append(idx)\n",
    "        \n",
    "        for idx, account in enumerate(accounts):\n",
    "            name = account[0]\n",
    "            emails = set()\n",
    "            if idx not in visited:\n",
    "                dfs(idx, emails)\n",
    "                res.append([name] + sorted(list(emails)))\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        email2Idx = collections.defaultdict(list)\n",
    "        n = len(accounts)\n",
    "        visited = set()\n",
    "        res = []\n",
    "        for i, acc in enumerate(accounts):\n",
    "            for email in acc[1:]:\n",
    "                email2Idx[email].append(i)\n",
    "        def dfs(idx, emails):\n",
    "            if idx in visited:\n",
    "                return\n",
    "            lst = accounts[idx][1:]\n",
    "            visited.add(idx)\n",
    "            for email in lst:\n",
    "                emails.add(email)\n",
    "                for nxt in email2Idx[email]:\n",
    "                    dfs(nxt, emails)\n",
    "        \n",
    "        for i in range(n):\n",
    "            if i not in visited:\n",
    "                name = accounts[i][0]\n",
    "                emails = set()\n",
    "                dfs(i, emails)\n",
    "                res.append([name] + sorted(list(emails)))\n",
    "        \n",
    "        return res\n",
    "\n",
    "\n",
    "                \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        g = defaultdict(list)\n",
    "        for _,mst,*a in accounts:\n",
    "            for eml in set([*a]):\n",
    "                g[mst].append(eml)\n",
    "                g[eml].append(mst)\n",
    "        \n",
    "        def dfs(x):\n",
    "            if x in vis:\n",
    "                return\n",
    "            vis.add(x)\n",
    "            emls.append(x)\n",
    "            for y in g[x]:\n",
    "                dfs(y)\n",
    "        ans = []\n",
    "        vis = set()\n",
    "        for act in accounts:\n",
    "            emls = []\n",
    "            dfs(act[1])\n",
    "            if emls:\n",
    "                ans.append([act[0]]+sorted(emls))\n",
    "        return ans\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        graph = collections.defaultdict(list)\n",
    "        for a in accounts:\n",
    "            master = a[1]\n",
    "            for e in list(set(a[2:])):\n",
    "                graph[master].append(e)\n",
    "                graph[e].append(master)\n",
    "        res = []\n",
    "        visited = set()\n",
    "\n",
    "        def dfs(e,emails):\n",
    "            if e in visited:\n",
    "                return\n",
    "            visited.add(e)\n",
    "            emails.append(e)\n",
    "            for i in graph[e]:\n",
    "                dfs(i,emails)\n",
    "            \n",
    "        for a in accounts:\n",
    "            emails = []\n",
    "            dfs(a[1],emails)\n",
    "            if emails:\n",
    "                res.append([a[0]]+sorted(emails))\n",
    "        return res\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\r\n",
    "\r\n",
    "from collections import defaultdict\r\n",
    "class Solution:\r\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\r\n",
    "        mail2idxs = defaultdict(list)\r\n",
    "        for idx, i in enumerate(accounts):\r\n",
    "            for mail in i[1:]:\r\n",
    "                mail2idxs[mail].append(idx)\r\n",
    "        # dfs\r\n",
    "        idx2idxs = defaultdict(list)\r\n",
    "        for i in mail2idxs.values():\r\n",
    "            for j in i:\r\n",
    "                idx2idxs[j].extend(i)\r\n",
    "        for k, v in mail2idxs.items():\r\n",
    "            mail2idxs[k] = set(v)\r\n",
    "        print(mail2idxs)\r\n",
    "        \r\n",
    "        res = []\r\n",
    "        visited = set()\r\n",
    "        def dfs(idx, cur: List):\r\n",
    "            cur.append(idx)\r\n",
    "            visited.add(idx)\r\n",
    "            for i in idx2idxs[idx]:\r\n",
    "                if i not in visited:\r\n",
    "                    dfs(i, cur)\r\n",
    "        for i in range(len(accounts)):\r\n",
    "            if i not in visited:\r\n",
    "                one_person = []\r\n",
    "                dfs(i, one_person)\r\n",
    "                email = []\r\n",
    "                for each in one_person:\r\n",
    "                    email.extend(accounts[each][1:])\r\n",
    "                \r\n",
    "                res.append([accounts[i][0]] + sorted(set(email)))\r\n",
    "                \r\n",
    "                    \r\n",
    "        return res\r\n",
    "\r\n",
    "\r\n",
    "\r\n",
    "print(Solution().accountsMerge(accounts = [[\"John\", \"johnsmith@mail.com\", \"john00@mail.com\"], [\"John\", \"johnnybravo@mail.com\"], [\"John\", \"johnsmith@mail.com\", \"john_newyork@mail.com\"], [\"Mary\", \"mary@mail.com\"]]))                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "class Solution:\n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        g = defaultdict(list)\n",
    "        for acc in accounts:\n",
    "            root = acc[1]\n",
    "            for email in acc[2:]:\n",
    "                g[root].append(email)\n",
    "                g[email].append(root)\n",
    "        def dfs(e):\n",
    "            for neighbour in g[e]:\n",
    "                if neighbour not in visited:\n",
    "                    emails.append(neighbour)\n",
    "                    visited.add(neighbour)\n",
    "                    dfs(neighbour)\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for acc in accounts:\n",
    "            name = acc[0]\n",
    "            emails = []\n",
    "            if acc[1] not in visited:\n",
    "                emails.append(acc[1])\n",
    "                visited.add(acc[1])\n",
    "                dfs(acc[1])\n",
    "            if emails:\n",
    "                res.append([name] + sorted(emails[:]))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def build_graph(self,accounts):\n",
    "\n",
    "        graph = collections.defaultdict(list)\n",
    "        for account in accounts:\n",
    "            master = account[1]\n",
    "            # 对剩余账户做一个去重\n",
    "            for email in list(set(account[2:])):\n",
    "                graph[master].append(email)\n",
    "                graph[email].append(master)\n",
    "        \n",
    "        return graph\n",
    "    \n",
    "    \n",
    "    \n",
    "    def accountsMerge(self, accounts: List[List[str]]) -> List[List[str]]:\n",
    "        def dfs(email):\n",
    "            \"\"\"\n",
    "            深搜遍历\n",
    "            \"\"\"\n",
    "            # 已经访问过的就剪枝\n",
    "            if email in visited:\n",
    "                return \n",
    "            \n",
    "            visited.add(email)\n",
    "            emails.append(email)\n",
    "            \n",
    "            # 对邻居节点继续深搜\n",
    "            for neighbor in graph[email]:\n",
    "                dfs(neighbor)\n",
    "\n",
    "        graph = self.build_graph(accounts)\n",
    "        res = []\n",
    "        visited = set()\n",
    "        for account in accounts:\n",
    "            emails = []\n",
    "            dfs(account[1])\n",
    "            if emails:\n",
    "                res.append([account[0]] + sorted(emails))\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        x, y = int(a, 2), int(b, 2)\n",
    "        while y:\n",
    "            x, y = x ^ y, (x & y) << 1\n",
    "        return bin(x)[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: 'str', b: 'str') -> 'str':\n",
    "        aInt=int(a,2)\n",
    "        bInt=int(b,2)\n",
    "        return bin(aInt+bInt)[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: 'str', b: 'str') -> 'str':\n",
    "        na, nb = len(a), len(b)\n",
    "        ret = ''\n",
    "        i, j = na - 1, nb - 1\n",
    "        carry = 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            if i >= 0:\n",
    "                va = int(a[i])\n",
    "                i -= 1\n",
    "            else:\n",
    "                va = 0\n",
    "            if j >= 0:\n",
    "                vb = int(b[j])\n",
    "                j -= 1\n",
    "            else:\n",
    "                vb = 0\n",
    "            v = (va + vb + carry) % 2\n",
    "            carry = (va + vb + carry) // 2\n",
    "            ret = str(v) + ret\n",
    "        if carry:\n",
    "            ret = '1' + ret\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: 'str', b: 'str') -> 'str':\n",
    "        a = a[::-1]\n",
    "        b = b[::-1]\n",
    "        temp = 0\n",
    "        for i in range(len(a)):\n",
    "            temp += int(a[i])*(2**i)\n",
    "        a_value = temp\n",
    "        temp = 0\n",
    "        for i in range(len(b)):\n",
    "            temp += int(b[i])*(2**i) \n",
    "        b_value = temp\n",
    "        add_value = a_value + b_value\n",
    "        print(a_value)\n",
    "        print(b_value)\n",
    "        print(add_value)\n",
    "        result = str()\n",
    "        while add_value>=2:\n",
    "            result += str(int(add_value%2))\n",
    "            add_value = add_value//2\n",
    "        result += str(int(add_value))\n",
    "        return result[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        len_a = len(a)\n",
    "        len_b = len(b)\n",
    "        result = []\n",
    "        longest = {}\n",
    "        if len_a < len_b:\n",
    "            num_min = len_a\n",
    "            longest.setdefault('a', b)\n",
    "            left = len_b-len_a\n",
    "        else:\n",
    "            num_min = len_b\n",
    "            longest.setdefault('a', a)\n",
    "            left = len_a-len_b\n",
    "        temp = 0\n",
    "        for index in range(1, num_min+1):\n",
    "            temp = temp+int(a[-index])+int(b[-index])\n",
    "            if temp >= 2:\n",
    "                result.insert(0, temp-2)\n",
    "                temp = 1\n",
    "            else:\n",
    "                result.insert(0, temp)\n",
    "                temp = 0\n",
    "        for index in range(left-1, -1, -1):\n",
    "            temp = temp+int(longest.get('a')[index])\n",
    "            if temp >= 2:\n",
    "                result.insert(0, temp-2)\n",
    "                temp = 1\n",
    "            else:\n",
    "                result.insert(0, temp)\n",
    "                temp = 0\n",
    "        if temp:\n",
    "            result.insert(0,temp)\n",
    "        return ''.join(str(x) for x in result)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        return bin(eval('0b' + a) + eval('0b' + b))[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        flag = 0\n",
    "        if len(a)>len(b):\n",
    "            b = '0'*(len(a)-len(b))+b\n",
    "        else:\n",
    "            a = '0'*(len(b)-len(a))+a\n",
    "        le = len(a)\n",
    "        print(a,b)\n",
    "        result = ''\n",
    "        \n",
    "        for i in range(le):\n",
    "            print(i)\n",
    "            num = int(a[le-i-1])+int(b[le-i-1])+flag\n",
    "            print('num',num)\n",
    "            if num==0:\n",
    "                result = '0'+result\n",
    "                flag = 0\n",
    "            if num==1:\n",
    "                result = '1'+result\n",
    "                flag = 0\n",
    "            if num==2:\n",
    "                result = '0'+result\n",
    "                flag = 1\n",
    "            if num==3:\n",
    "                result = '1'+result\n",
    "                flag = 1\n",
    "            if i==le-1 and flag==1:\n",
    "                result = '1'+result\n",
    "        \n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        \n",
    "        lena=len(a)\n",
    "        lenb=len(b)\n",
    "        carry=0\n",
    "        result=[]\n",
    "        num=max(lena,lenb)\n",
    "        if num==lena:\n",
    "            b=(lena-lenb)*'0'+b\n",
    "        elif num==lenb:\n",
    "            a=(lenb-lena)*'0'+a\n",
    "        a=list(map(int,list(a)))\n",
    "        b=list(map(int,list(b)))\n",
    "        for i in reversed(range(num)):\n",
    "            if a[i]+b[i]+carry>1:\n",
    "                \n",
    "                print(i,a[i],b[i],carry,(a[i]+b[i]+carry)%2)\n",
    "                result.append((a[i]+b[i]+carry)%2)\n",
    "                carry=1\n",
    "            else:\n",
    "                \n",
    "                result.append(a[i]+b[i]+carry)\n",
    "                carry=0\n",
    "        result.append(carry)\n",
    "        print(''.join(list(map(str,result[::-1]))))\n",
    "        return str(int(''.join(list(map(str,result[::-1])))))\n",
    "            \n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        return bin(int(a,2)+int(b,2))[2:]\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        return str(bin(int(a,2) + int(b,2)))[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        c = 0\n",
    "        a = a[::-1]\n",
    "        b = b[::-1]\n",
    "        la = len(a)\n",
    "        lb = len(b)\n",
    "        print(a, b)\n",
    "        result = []\n",
    "        i = 0\n",
    "        while i < la or i < lb:\n",
    "            if i >= la:\n",
    "                ta = 0\n",
    "            else:\n",
    "                ta = int(a[i])  \n",
    "            if i >= lb:\n",
    "                tb = 0\n",
    "            else:\n",
    "                tb = int(b[i])\n",
    "            \n",
    "            d =  ta + tb + c\n",
    "            print(ta, tb, c, d)\n",
    "            if d < 2:\n",
    "                c = 0\n",
    "            else:\n",
    "                c = 1\n",
    "            result.append(str(d%2))\n",
    "            i += 1\n",
    "            \n",
    "        if c==1:\n",
    "            result.append('1')\n",
    "            \n",
    "        return \"\".join(result[::-1])\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        #入参检查\n",
    "        if len(a) == 0:\n",
    "            return b\n",
    "        elif len(b) == 0:\n",
    "            return a\n",
    "\n",
    "        #补0\n",
    "        zeros = abs(len(a) - len(b))\n",
    "\n",
    "        if len(a) >= len(b):\n",
    "            b = '0' * zeros + b\n",
    "            max_len = len(a)\n",
    "        else:\n",
    "            a = '0' * zeros + a\n",
    "            max_len = len(b)\n",
    "\n",
    "        carry = 0\n",
    "        string = ''\n",
    "        for i in range(1, max_len+1):\n",
    "            print(a[-i], b[-i])\n",
    "            sum = int(a[-i]) + int(b[-i]) + carry\n",
    "            if sum == 0:\n",
    "                string = '0' + string\n",
    "                carry = 0\n",
    "            elif sum == 1:\n",
    "                string = '1' + string\n",
    "                carry = 0\n",
    "            elif sum == 2:\n",
    "                string = '0' + string\n",
    "                carry = 1\n",
    "            else:\n",
    "                string = '1' + string\n",
    "                carry = 1\n",
    "\n",
    "        if carry:\n",
    "            string = '1' + string\n",
    "\n",
    "        return string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        if a == \"\" and b == \"\":\n",
    "            return \"\"\n",
    "        \n",
    "        i = a[-1] if a else \"0\"\n",
    "        j = b[-1] if b else \"0\"\n",
    "\n",
    "        k = int(i) + int(j)\n",
    "        print(k)\n",
    "        if k == 0:\n",
    "            return self.addBinary(a[0:-1], b[0:-1]) + \"0\"\n",
    "        elif k == 1:\n",
    "            return self.addBinary(a[0:-1], b[0:-1]) + \"1\"\n",
    "        elif k == 2:\n",
    "            return self.addBinary(self.addBinary(a[0:-1], b[0:-1]), \"1\") + \"0\"\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b):\n",
    "        \"\"\"\n",
    "        :type a: str\n",
    "        :type b: str\n",
    "        :rtype: str\n",
    "        \"\"\"\n",
    "        c = 0\n",
    "        a = a[::-1]\n",
    "        b = b[::-1]\n",
    "        la = len(a)\n",
    "        lb = len(b)\n",
    "        result = []\n",
    "        i = 0\n",
    "        while i < la or i < lb:\n",
    "            if i >= la:\n",
    "                ta = 0\n",
    "            else:\n",
    "                ta = int(a[i])  \n",
    "            if i >= lb:\n",
    "                tb = 0\n",
    "            else:\n",
    "                tb = int(b[i])\n",
    "            \n",
    "            d =  ta + tb + c\n",
    "            print(ta, tb, c, d)\n",
    "            if d < 2:\n",
    "                c = 0\n",
    "            else:\n",
    "                c = 1\n",
    "            result.append(str(d%2))\n",
    "            i += 1\n",
    "            \n",
    "        if c==1:\n",
    "            result.append('1')\n",
    "            \n",
    "        return \"\".join(result[::-1])\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: 'str', b: 'str') -> 'str':\n",
    "        return bin(int(a, 2) + int(b, 2))[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution1:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        ans,i,j,c = \"\",len(a)-1,len(b)-1,0\n",
    "        while i >= 0 and j >= 0:\n",
    "            tmp = int (a[i]) + int (b[j]) + c \n",
    "            ans += str(tmp%2)\n",
    "            c = tmp//2\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        while i >= 0:\n",
    "            tmp = int (a[i]) + c \n",
    "            ans += str(tmp%2)\n",
    "            c = tmp//2\n",
    "            i -= 1\n",
    "        while j >= 0:\n",
    "            tmp = int (b[j]) + c \n",
    "            ans += str(tmp%2)\n",
    "            c = tmp//2\n",
    "            j -= 1\n",
    "        ans = ans if c == 0 else ans+str(c)\n",
    "        return ans[::-1]\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        return bin(int(a,2)+int(b,2))[2:]\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    print(Solution().addBinary(\"1101\",\"1111\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        a_ten = self.binary_ten(a)\n",
    "        b_ten = self.binary_ten(b)\n",
    "        sum_ten = a_ten + b_ten\n",
    "        sum_binary = self.ten_binary(sum_ten)\n",
    "        return sum_binary\n",
    "\n",
    "    def binary_ten(self,s ):\n",
    "        length = len(s)\n",
    "        ten_number = 0\n",
    "        for _ in range(length):\n",
    "            ten_number += int(math.pow(2, length-_-1)) * int(s[_])\n",
    "        return ten_number\n",
    "    def ten_binary(self, s):\n",
    "        if s == 0:\n",
    "            return \"0\"\n",
    "        binary_number = \"\"\n",
    "        while s > 0:\n",
    "            binary_number += str(s % 2)\n",
    "            s = s // 2\n",
    "        binary_number = binary_number[::-1]\n",
    "        return binary_number"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        if len(a) < len(b):\n",
    "            a,b = b,a\n",
    "        n = len(a)\n",
    "        b = (n - len(b))*'0' + b\n",
    "        res = ''\n",
    "        add = 0\n",
    "        for i in range(n):\n",
    "            num_a = int(a[n-i-1])\n",
    "            num_b = int(b[n-i-1])\n",
    "            res = str(( num_a+ num_b + add) % 2) + res\n",
    "            add = (num_a+ num_b + add) // 2 \n",
    "        if add == 1:\n",
    "            res = '1' + res\n",
    "        return res\n",
    "            \n",
    "            \n",
    "            \n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        return bin(int(a,2) + int(b,2))[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        # return bin(int(a,2)+int(b,2))[2:]   bin()将数字转为二进制，int(a,2)将字符串a转为二进制整型  bint()[2:0]去掉\"0b\"取后面的数\n",
    "        sum = []\n",
    "        tmp = 0\n",
    "        a = list(a)\n",
    "        b = list(b)\n",
    "        while(len(a) and len(b)):\n",
    "            pa = int(a.pop())\n",
    "            pb = int(b.pop())\n",
    "            sum1 = str((pa+pb+tmp)%2)\n",
    "            tmp = (pa+pb+tmp) //2\n",
    "            sum.insert(0,sum1)\n",
    "        if len(a):\n",
    "            if tmp == 1:\n",
    "                while(len(a)):\n",
    "                    pa = int(a.pop())\n",
    "                    sum1 = str((tmp+pa)%2)\n",
    "                    tmp = (tmp+pa) // 2\n",
    "                    sum.insert(0,sum1)\n",
    "            else:\n",
    "                a = \"\".join(a)\n",
    "                sum.insert(0,a)\n",
    "        if len(b):\n",
    "            if tmp == 1:\n",
    "                while(len(b)):\n",
    "                    pb = int(b.pop())\n",
    "                    sum1 = str((tmp+pb)%2)\n",
    "                    tmp = (tmp+pb) // 2\n",
    "                    sum.insert(0,sum1)\n",
    "            else:\n",
    "                b = \"\".join(b)\n",
    "                sum.insert(0,b)\n",
    "        if tmp == 1:\n",
    "            sum.insert(0,'1')\n",
    "        sum = \"\".join(sum) \n",
    "        return sum \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        carry=0\n",
    "        m,n=len(a),len(b)\n",
    "        if m>n:\n",
    "            b='0'*(m-n)+b \n",
    "        else:\n",
    "            a='0'*(n-m)+a \n",
    "        res=\"\"\n",
    "        for i in range(len(a)-1,-1,-1):\n",
    "            temp=int(a[i])+int(b[i])+carry\n",
    "            if temp>=2:\n",
    "                res=str(temp-2)+res\n",
    "                carry=1\n",
    "            else:\n",
    "                res=str(temp)+res\n",
    "                carry=0\n",
    "        if carry==1:\n",
    "            res='1'+res\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        c = int(a) + int(b)\n",
    "        if not c: return '0'\n",
    "        ans = ''\n",
    "        while c >= 1:\n",
    "            rest = c % 10\n",
    "            if rest > 1:\n",
    "                ans = str(rest - 2) + ans\n",
    "                c = (c // 10) + 1\n",
    "            else:\n",
    "                ans = str(rest) + ans\n",
    "                c = c // 10\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        return bin(int(a,2)+int(b,2))[2:]\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a, b) -> str:\n",
    "        return '{0:b}'.format(int(a, 2) + int(b, 2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        int_a = int(a)\n",
    "        int_b = int(b)\n",
    "        int_re = int_a+int_b\n",
    "        list_re = [int(i) for i in list(str(int_re))]\n",
    "        for i in range(-1,-len(list_re)-1,-1):\n",
    "            print(i,list_re[i])\n",
    "            if list_re[i] >= 2 and i > -len(list_re):\n",
    "                list_re[i] = list_re[i] -2\n",
    "                list_re[i-1] += 1\n",
    "            elif list_re[i] >= 2 and i == -len(list_re):\n",
    "                list_re[i] = list_re[i] -2\n",
    "                list_re.insert(0,1)\n",
    "        return \"\".join([str(i) for i in list_re])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        m=max(len(a),len(b))\n",
    "        a=list(reversed(list(a)))\n",
    "        b=list(reversed(list(b)))\n",
    "        if len(a) ==m:\n",
    "            b.extend(['0' for i in range(0,m-len(b)+1)])\n",
    "            a.append('0')\n",
    "        else:\n",
    "            a.extend(['0' for i in range(0,m-len(a)+1)])\n",
    "            b.append('0')\n",
    "        s=[]\n",
    "        def binaryadd(a,b,n,d):\n",
    "            while n>=0:\n",
    "                c=int(a[0])+int(b[0])+d-2\n",
    "                if c>=0:\n",
    "                    d=1\n",
    "                    s.append(str(c))\n",
    "                else:\n",
    "                    d=0\n",
    "                    s.append(str(c+2))\n",
    "                return binaryadd(a[1::],b[1::],n-1,d)\n",
    "            else:\n",
    "                if d ==1:\n",
    "                    s.append('1')\n",
    "                else:\n",
    "                    s.append('0')\n",
    "        binaryadd(a,b,m,0)\n",
    "        result=''.join(list(reversed(s)))\n",
    "        if result[0]=='0':\n",
    "            if result[1]=='0':\n",
    "                result=result[2::]\n",
    "            else:\n",
    "                result=result[1::]\n",
    "        return result\n",
    "\n",
    "                \n",
    "                \n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        arr_a = list(a)\n",
    "        arr_b = list(b)\n",
    "        la = len(arr_a)\n",
    "        lb = len(arr_b)\n",
    "        \n",
    "        if la > lb:\n",
    "            arr_b = ['0' for i in range(la-lb)] + arr_b\n",
    "            \n",
    "        if lb > la:\n",
    "            arr_a = ['0' for i in range(lb-la)] + arr_a\n",
    "        \n",
    "        arr_c = ['0' for i in range(len(arr_a))]\n",
    "        next_c = '0'\n",
    "        for i in range(len(arr_a)-1, -1, -1):\n",
    "            print(arr_a[i], arr_b[i])\n",
    "            if arr_a[i] == '1' and arr_b[i] == '1':\n",
    "                if next_c == '1':\n",
    "                    arr_c[i] = '1'\n",
    "                else:\n",
    "                    arr_c[i] = '0'\n",
    "                next_c = '1'\n",
    "            elif (arr_a[i] == '1' and arr_b[i] == '0') or (arr_a[i] == '0' and arr_b[i] == '1'):\n",
    "                if next_c == '1':\n",
    "                    arr_c[i] = '0'\n",
    "                    next_c = '1'  \n",
    "                else:\n",
    "                    arr_c[i] = '1'\n",
    "            elif arr_a[i] == '0' or arr_b[i] == '0':\n",
    "                if next_c == '1':\n",
    "                    arr_c[i] = '1'                    \n",
    "                else:\n",
    "                    arr_c[i] = '0' \n",
    "                next_c = '0'  \n",
    "\n",
    "        if next_c == '1':\n",
    "            arr_c = ['1'] + arr_c\n",
    "            \n",
    "        return ''.join(str(i) for i in arr_c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        a = int(a,2)\n",
    "        b = int(b,2)\n",
    "\n",
    "        c = a+b\n",
    "        c = bin(c)\n",
    "        return c[2::]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(a) - 1, len(b) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            sum = carry\n",
    "            sum += ord(a[i]) - ord(\"0\") if i >= 0 else 0\n",
    "            sum += ord(b[j]) - ord(\"0\") if j >= 0 else 0\n",
    "            res += str(sum % 2)\n",
    "            carry = sum // 2\n",
    "            i, j = i - 1, j - 1\n",
    "        if carry > 0:\n",
    "            res += str(carry)\n",
    "        return res[::-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        flag = 0\n",
    "        c = \"\"\n",
    "        for i in range(-1, - min(len(a), len(b)) - 1, -1):\n",
    "            temp = int(a[i]) + int(b[i]) + flag\n",
    "            c += str(temp % 2)\n",
    "            flag = temp // 2\n",
    "        if len(a) > len(b):\n",
    "            for i in a[-len(b) - 1::-1]:\n",
    "                temp = int(i) + flag\n",
    "                c += str(temp % 2)\n",
    "                flag = temp // 2\n",
    "        else:\n",
    "            for i in b[-len(a) - 1::-1]:\n",
    "                temp = int(i) + flag\n",
    "                c += str(temp % 2)\n",
    "                flag = temp // 2\n",
    "        if flag == 1:\n",
    "            c += \"1\"\n",
    "        return c[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        flag = 0\n",
    "        c = \"\"\n",
    "        for i in range(-1, - min(len(a), len(b)) - 1, -1):\n",
    "            temp = int(a[i]) + int(b[i]) + flag\n",
    "            c += str(temp % 2)\n",
    "            flag = temp // 2\n",
    "        if len(a) > len(b):\n",
    "            for i in a[-len(b) - 1::-1]:\n",
    "                temp = int(i) + flag\n",
    "                c += str(temp % 2)\n",
    "                flag = temp // 2\n",
    "        else:\n",
    "            for i in b[-len(a) - 1::-1]:\n",
    "                temp = int(i) + flag\n",
    "                c += str(temp % 2)\n",
    "                flag = temp // 2\n",
    "        if flag == 1:\n",
    "            c += \"1\"\n",
    "        return c[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def addBinary(self, a: str, b: str) -> str:\r\n",
    "        s = []\r\n",
    "        c = 0\r\n",
    "        for i in range(max(len(a), len(b))):\r\n",
    "            bit_a = int(a[-i-1]) if i < len(a) else 0\r\n",
    "            bit_b = int(b[-i-1]) if i < len(b) else 0\r\n",
    "            sum = bit_a + bit_b + c\r\n",
    "            s.append(str(sum % 2))\r\n",
    "            c = 1 if sum >= 2 else 0\r\n",
    "        if c == 1:\r\n",
    "            s.append('1')\r\n",
    "        return \"\".join(s[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        return bin(int(a,2) + int(b,2))[2:]\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        return bin(int(a,2) + int(b,2))[2:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        ab = int(a) + int(b)\n",
    "        dp = [0] + list(map(int,str(ab)))\n",
    "        for i in range(len(dp)-1,-1,-1):\n",
    "            if dp[i] >= 2:\n",
    "                dp[i-1] += dp[i] // 2\n",
    "                dp[i] -= 2\n",
    "        if a == '0' and b == '0':\n",
    "            return '0'\n",
    "        return(''.join(map(str, dp)).lstrip('0'))\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBinary(self, a: str, b: str) -> str:\n",
    "        return bin(int(a,2)+int(b,2))[2:]\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        s_len = len(s)\n",
    "        mask = [False for i in range(s_len)]\n",
    "\n",
    "        for index in range(s_len):\n",
    "            for word in words:\n",
    "                word_len = len(word)\n",
    "                if index + word_len <= s_len and s[index: word_len + index] == word:\n",
    "                    for j in range(index, index + word_len):\n",
    "                        mask[j] = True\n",
    "\n",
    "        res = []\n",
    "\n",
    "        for index in range(s_len):\n",
    "            if mask[index] and (index == 0 or not mask[index - 1]):\n",
    "                res.append(\"<b>\")\n",
    "            res.append(s[index])\n",
    "            if mask[index] and (index == s_len - 1 or not mask[index + 1]):\n",
    "                res.append(\"</b>\")\n",
    "\n",
    "        return \"\".join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        # list_s = list(s)\n",
    "        # dic = defaultdict(list)\n",
    "        # for w in words:\n",
    "        #     dic[w] = [i for i in range(len(s)) if \"\".join(list_s[i:i+len(w)]) == w]\n",
    "        #     # print(dic[w])\n",
    "        #     dic[w].append(dic[w][0]+len(w))\n",
    "        # print(dic)\n",
    "        N = len(s)\n",
    "        mask = [False] *N\n",
    "        for i in range(N):\n",
    "            prefix = s[i:]\n",
    "            for word in words:\n",
    "                if prefix.startswith(word):\n",
    "                    for j in range(i,min(i+len(word), N)):\n",
    "                        mask[j] = True\n",
    "        ans = []\n",
    "        for i in range(N):\n",
    "            if mask[i] and (i==0 or not mask[i-1]):\n",
    "                ans.append('<b>')\n",
    "            ans.append(s[i])\n",
    "            if mask[i] and (i==N-1 or not mask[i+1]):\n",
    "                ans.append('</b>')\n",
    "        return \"\".join(ans)  \n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 枚举法\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "      n = len(s)\n",
    "      mask = [False] * n\n",
    "      for i in range(n):\n",
    "        prefix = s[i:]\n",
    "        for word in words:\n",
    "          if prefix.startswith(word):\n",
    "            for j in range(i, min(i+len(word), n)):\n",
    "              mask[j] = True\n",
    "      \n",
    "      res = []\n",
    "      # groupby支持两个参数，第一个参数是需要迭代的对象，第二个函数key代表分组依据，如果为none则表示使用迭代对象中的元素作为分组依据\n",
    "      for incl, grp in itertools.groupby(zip(s, mask), lambda z: z[1]):\n",
    "        if incl: res.append('<b>')\n",
    "        res.append(''.join(z[0] for z in grp))\n",
    "        if incl: res.append('</b>')\n",
    "      return ''.join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        site = []\n",
    "        for i in range(len(s)):\n",
    "            for word in words:\n",
    "                if s[i:i + len(word)] == word:\n",
    "                    a = i\n",
    "                    b = i + len(word)\n",
    "                    if site and site[-1][-1] >= a:\n",
    "                        site[-1][-1] = max(b, site[-1][-1])\n",
    "                    else:\n",
    "                        site.append([a, b])\n",
    "        ans = ''\n",
    "        i = 0\n",
    "        n = len(s)\n",
    "        now = 0\n",
    "        while i < n:\n",
    "            if now < len(site) and i == site[now][0]:\n",
    "                ans += '<b>' + s[i:site[now][1]] + '</b>'\n",
    "                i = site[now][1]\n",
    "                now += 1\n",
    "            else:\n",
    "                ans += s[i]\n",
    "                i += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        s_len = len(s)\n",
    "        mask = [False for i in range(s_len)]\n",
    "\n",
    "        for index in range(s_len):\n",
    "            for word in words:\n",
    "                word_len = len(word)\n",
    "                if   s[index: word_len + index] == word:\n",
    "                    for j in range(index, index + word_len):\n",
    "                        mask[j] = True\n",
    "\n",
    "        res = []\n",
    "\n",
    "        for index in range(s_len):\n",
    "            if mask[index] and (index == 0 or not mask[index - 1]):\n",
    "                res.append(\"<b>\")\n",
    "            res.append(s[index])\n",
    "            if mask[index] and (index == s_len - 1 or not mask[index + 1]):\n",
    "                res.append(\"</b>\")\n",
    "\n",
    "        return \"\".join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "\n",
    "        mask = [False] * n\n",
    "\n",
    "        for idx in range(n):\n",
    "            for word in words:\n",
    "                wl = len(word)\n",
    "                if s[idx: idx+wl] == word:\n",
    "                    for i in range(idx, idx+wl):\n",
    "                        mask[i] = True\n",
    "        \n",
    "        res = ''\n",
    "        match = False\n",
    "        for i, v in enumerate(mask):\n",
    "            if v and not match:\n",
    "                res += '<b>'\n",
    "                match = True\n",
    "            \n",
    "            elif not v and match:\n",
    "                res += '</b>'\n",
    "                match = False\n",
    "            \n",
    "            res += s[i]\n",
    "        \n",
    "        if match:\n",
    "            res += '</b>'\n",
    "        \n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        mask = [False] * n\n",
    "        end = 0\n",
    "        for i in range(n):\n",
    "            for word in words:\n",
    "                if s[i:].startswith(word):\n",
    "                    end = max(end, i + len(word))\n",
    "            if i < end:\n",
    "                mask[i] = True\n",
    "        ans = \"\"\n",
    "        i = 0\n",
    "        while i < n:\n",
    "            if mask[i]:\n",
    "                j = i\n",
    "                while j < n and mask[j]:\n",
    "                    j += 1\n",
    "                ans += \"<b>\" + s[i:j] + \"</b>\"\n",
    "                i = j\n",
    "            else:\n",
    "                ans += s[i]\n",
    "                i += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        mask = [False]*n\n",
    "\n",
    "        for i in range(n):\n",
    "            for x in words:\n",
    "                if i + len(x) <= n and s[i:i + len(x)] == x:\n",
    "                    for j in range(i,i + len(x)):\n",
    "                        mask[j] = True\n",
    "        ans = ''\n",
    "        for i in range(n):\n",
    "            if mask[i] and (i == 0 or mask[i - 1] == False):\n",
    "                ans += '<b>'\n",
    "            ans += s[i]\n",
    "\n",
    "            if mask[i] and (i == n - 1 or mask[i + 1] == False):\n",
    "                ans += '</b>'\n",
    "\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        mask = [0] * len(s)\n",
    "        for i in range(len(s)):\n",
    "            for word in words:\n",
    "                if s[i:].startswith(word):\n",
    "                    mask[i:i+len(word)] = [1] * len(word)\n",
    "        res = \"\"\n",
    "        for i in range(len(s)):\n",
    "            if mask[i] == 1 and (i == 0 or mask[i - 1] == 0):\n",
    "                res += \"<b>\"\n",
    "            res += s[i]\n",
    "            if mask[i] == 1 and (i == len(s) - 1 or mask[i + 1] == 0):\n",
    "                res += \"</b>\"\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        # time complexity: O(n + w * n^2 + n) \n",
    "        # space complexity: O(n)\n",
    "\n",
    "        \"\"\"\n",
    "        首先，我们可以为字符串s中的每个字符标记一个布尔值，指示该字符是否需要加粗\n",
    "        使用一次遍历来确定需要加粗的范围\n",
    "\n",
    "        \"\"\"\n",
    "        n = len(s)\n",
    "        bold = [False] * n\n",
    "\n",
    "        for word in words:\n",
    "            index = 0\n",
    "            while index < n:\n",
    "                start = s.find(word, index)\n",
    "                if start == -1:\n",
    "                    break\n",
    "                \n",
    "                end = start + len(word)\n",
    "\n",
    "                for i in range(start, end):\n",
    "                    bold[i] = True\n",
    "                index += 1\n",
    "\n",
    "\n",
    "        result = []\n",
    "        for i in range(n):\n",
    "            if bold[i] and (i == 0 or not bold[i - 1]):\n",
    "                result.append(\"<b>\")\n",
    "            result.append(s[i])\n",
    "            if bold[i] and (i == n - 1 or not bold[i + 1]):\n",
    "                result.append(\"</b>\")\n",
    "        \n",
    "        return \"\".join(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        intervals = []\n",
    "        for i in range(len(s)):\n",
    "            for w in words:\n",
    "                if s[i:len(w) + i] == w:\n",
    "                    if intervals:\n",
    "                        l, r = intervals[-1]\n",
    "                        if i <= r + 1:\n",
    "                            intervals[-1][1] = max(len(w)+i-1, r)\n",
    "                            break\n",
    "                    intervals.append([i, len(w)+i-1])\n",
    "        res = ''\n",
    "        i = j = 0\n",
    "        while i < len(s):\n",
    "            if j < len(intervals):\n",
    "                l, r = intervals[j]\n",
    "                if i < l:\n",
    "                    res += s[i]\n",
    "                    i +=1\n",
    "                else:\n",
    "                    res += '<b>' + s[i:r + 1] + '</b>'\n",
    "                    i = r + 1\n",
    "                    j +=1\n",
    "            else:\n",
    "                res += s[i:]\n",
    "                break\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        mask = [False] * n\n",
    "        for i in range(n):\n",
    "            prefix = s[i:]\n",
    "            for word in words:\n",
    "                if prefix.startswith(word):\n",
    "                    for j in range(len(word)):\n",
    "                        mask[i+j] = True\n",
    "        ans = []\n",
    "        for i in range(n):\n",
    "            m = mask[i]\n",
    "            pre = mask[i-1] if i > 0 else False\n",
    "            after = mask[i+1] if i + 1 < n else False\n",
    "            if not pre and m:\n",
    "                ans.append('<b>')\n",
    "            ans.append(s[i])\n",
    "            if not after and m:\n",
    "                ans.append('</b>')\n",
    "        return \"\".join(ans)\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n=len(s)\n",
    "        mask=[False]*n\n",
    "        for word in words:\n",
    "            for i in range(n-len(word)+1):\n",
    "                if s[i:i+len(word)]==word:\n",
    "                    #修改mask,有点差分的味道\n",
    "                    mask[i:i+len(word)]=[True]*len(word)\n",
    "        res=[]\n",
    "        for i in range(n):\n",
    "            if mask[i] and (i==0 or not mask[i-1]):\n",
    "                res.append(\"<b>\")\n",
    "            res.append(s[i])\n",
    "            if mask[i] and (i==n-1 or not mask[i+1]):\n",
    "                res.append(\"</b>\")\n",
    "        return \"\".join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n=len(s)\n",
    "        mask=[False]*n\n",
    "        for word in words:\n",
    "            for i in range(n-len(word)+1):\n",
    "                if s[i:i+len(word)]==word:\n",
    "                    #修改mask,有点差分的味道\n",
    "                    mask[i:i+len(word)]=[True]*len(word)\n",
    "        res=[]\n",
    "        for i in range(n):\n",
    "            if mask[i] and (i==0 or not mask[i-1]):\n",
    "                res.append(\"<b>\")\n",
    "            res.append(s[i])\n",
    "            if mask[i] and (i==n-1 or not mask[i+1]):\n",
    "                res.append(\"</b>\")\n",
    "        return \"\".join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "\n",
    "        bolded = [False] * len(s)\n",
    "\n",
    "        for word in words:\n",
    "            start = s.find(word)\n",
    "            while start != -1:\n",
    "                for i in range(start, start + len(word)):\n",
    "                    bolded[i] = True\n",
    "                start = s.find(word, start + 1)\n",
    "\n",
    "        ans = []\n",
    "        for i, char in enumerate(s):\n",
    "            if bolded[i] and (i == 0 or not bolded[i - 1]):\n",
    "                ans.append(\"<b>\")\n",
    "            ans.append(char)\n",
    "            if bolded[i] and (i == len(s) - 1 or not bolded[i + 1]):\n",
    "                ans.append(\"</b>\")\n",
    "\n",
    "        return \"\".join(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        mask = [False] * len(s)\n",
    "\n",
    "        for word in words:\n",
    "            start = s.find(word)\n",
    "            while start != -1:\n",
    "                for i in range(start, start + len(word)):\n",
    "                    mask[i] = True\n",
    "                start = s.find(word, start + 1)\n",
    "        \n",
    "        result = []\n",
    "        for i in range(len(s)):\n",
    "            if mask[i] and (i == 0 or not mask[i - 1]):\n",
    "                result.append('<b>')\n",
    "            result.append(s[i])\n",
    "            if mask[i] and (i == len(s) - 1 or not mask[i + 1]):\n",
    "                result.append('</b>')\n",
    "        \n",
    "        return ''.join(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        N = len(s) \n",
    "        mask = [False for _ in range(N)]\n",
    "        for i in range(N):\n",
    "            prefix = s[i:]\n",
    "            for word in words:\n",
    "                if prefix.startswith(word):\n",
    "                    for j in range(i, min(i+len(word), N)):\n",
    "                        mask[j] = True\n",
    "        ans = \"\"\n",
    "        for i in range(N):\n",
    "            if mask[i]==1 and (i==0 or mask[i-1]==0):\n",
    "                ans +=\"<b>\"\n",
    "            ans += s[i]\n",
    "            if mask[i]==1 and (i==N-1 or mask[i+1]==0):\n",
    "                ans+= \"</b>\"\n",
    "        return ans\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        memo = [0] * (n+2)\n",
    "        for word in words:\n",
    "            curLen = len(word)\n",
    "            start = 0\n",
    "            while start < n:\n",
    "                tmp = s.find(word,start)\n",
    "                if tmp == -1:\n",
    "                    break\n",
    "                else:\n",
    "                    memo[tmp+1] += 1\n",
    "                    memo[tmp+curLen+1] -= 1\n",
    "                    start = tmp + 1\n",
    "        for i in range(1,n+1):\n",
    "            memo[i] = memo[i] + memo[i-1]\n",
    "        print(memo)\n",
    "        res = \"\"\n",
    "        find = False\n",
    "        for i in range(n):\n",
    "            if find == False:\n",
    "                if memo[i+1] > 0:\n",
    "                    find = True\n",
    "                    res += \"<b>\"\n",
    "                res += s[i]\n",
    "            else:\n",
    "                if memo[i+1] == 0:\n",
    "                    find = False\n",
    "                    res += \"</b>\"\n",
    "                res += s[i]\n",
    "        if find:\n",
    "            res += \"</b>\"\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        b = [False]*n\n",
    "        for i in range(n):\n",
    "            prefix = s[i:]\n",
    "            max_len = 0\n",
    "            for word in words:\n",
    "                if prefix.startswith(word): max_len = max(max_len,len(word))\n",
    "            b[i:i+max_len] = [True]*max_len\n",
    "        \n",
    "        res = \"\"\n",
    "        for i in range(n):\n",
    "            if b[i]==True and (i==0 or b[i-1]==False): res+=\"<b>\"\n",
    "            res+=s[i]\n",
    "            if b[i]==True and (i==n-1 or b[i+1]==False): res+=\"</b>\"\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        result, p, prev = '', [0] * (len(s)+1), 0\n",
    "        for w in words:\n",
    "            i, n = s.find(w), len(w)\n",
    "            while i >= 0:\n",
    "                p[i] += 1\n",
    "                p[i+n] -= 1\n",
    "                i = s.find(w, i+1)\n",
    "        for c, x in zip_longest(s, accumulate(p), fillvalue=''):\n",
    "            if x and not prev:\n",
    "                result += '<b>'\n",
    "            elif not x and prev:\n",
    "                result += '</b>'\n",
    "            result += c\n",
    "            prev = x\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        mask = [0] * n\n",
    "        for i in range(n):\n",
    "            for word in words:\n",
    "                if s[i:].startswith(word):\n",
    "                    for j in range(i, i+len(word)):\n",
    "                        mask[j] = 1\n",
    "        \n",
    "        res = ''\n",
    "        start = False\n",
    "        for i in range(n):\n",
    "            if mask[i]:\n",
    "                if start:\n",
    "                    res += s[i]\n",
    "                else:\n",
    "                    start = True\n",
    "                    res += '<b>' + s[i]\n",
    "            else:\n",
    "                if start:\n",
    "                    res += '</b>'\n",
    "                    start = False\n",
    "                res += s[i]\n",
    "        if start:\n",
    "            res += '</b>'\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        mask = [False] * len(s)\n",
    "        for word in words:\n",
    "            for i in range(len(s)):\n",
    "                if s[i:].startswith(word):\n",
    "                    mask[i: i+len(word)] = [True] * len(word)\n",
    "        \n",
    "        res = \"\"\n",
    "        for i in range(len(s)):\n",
    "            if mask[i] and (i==0 or mask[i-1]==False):\n",
    "                res += \"<b>\"\n",
    "            res += s[i]\n",
    "            if mask[i] and (i==len(s)-1 or mask[i+1]==False):\n",
    "                res += \"</b>\"\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        inter =[]\n",
    "        for i in range(0, len(s)):\n",
    "            for j in range(0,i+1):\n",
    "                if s[j:i+1] in words:\n",
    "                    inter.append((j,i))\n",
    "                    break\n",
    "\n",
    "        i = 1\n",
    "        while len(inter) > i:\n",
    "            flag = -1\n",
    "            for j in range(0, i):\n",
    "                if inter[i][0] <= inter[j][1]:\n",
    "                    if inter[i][0] > inter[j][0]:\n",
    "                        inter = inter[:j] + [(inter[j][0], inter[i][1])] + inter[i+1:]\n",
    "                    else:\n",
    "                        inter = inter[:j] + [(inter[i][0], inter[i][1])] + inter[i+1:]\n",
    "                    i = j+1\n",
    "                    flag = 1\n",
    "                    break\n",
    "            if flag == -1: i+=1\n",
    "\n",
    "        i = 1\n",
    "        while len(inter) > i:\n",
    "            if inter[i][0]-inter[i-1][1] == 1:\n",
    "                inter = inter[:i-1] + [(inter[i-1][0], inter[i][1])] + inter[i+1:]\n",
    "                continue\n",
    "            i+=1\n",
    "\n",
    "        i , j = 0,0\n",
    "        res = []\n",
    "        for cur in range(0, len(s)):\n",
    "            if i< len(inter) and cur == inter[i][0]:\n",
    "                if len(res) > 0 and res[-1] == \"</b>\":\n",
    "                    res = res[:-1] + [s[cur]]\n",
    "                else:\n",
    "                    res = res + [\"<b>\" ,s[cur]]\n",
    "                i +=1\n",
    "                if j < len(inter) and cur == inter[j][1]:\n",
    "                    res = res + [\"</b>\"]\n",
    "                    j +=1\n",
    "            elif j < len(inter) and cur == inter[j][1]:\n",
    "                res = res + [s[cur] , \"</b>\"]\n",
    "                j +=1\n",
    "            else:\n",
    "                res = res + [s[cur]]\n",
    "        \n",
    "        return \"\".join(res)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        mark = [0] * len(s)\n",
    "        res = []\n",
    "        for word in words:\n",
    "            for i in range(len(word)-1, len(s)):\n",
    "                if word == s[i-len(word)+1: i+1]:\n",
    "                    mark[i-len(word)+1: i+1] = [1 for x in range(len(word))]\n",
    "        i = 0\n",
    "        j = 0\n",
    "        while i < len(mark):\n",
    "            if mark[i] == 1:\n",
    "                res.append(s[j:i])\n",
    "                res.append('<b>')\n",
    "                j = i + 1\n",
    "                while j < len(mark) and mark[j] == 1:\n",
    "                    j += 1\n",
    "                res.append(s[i: j])\n",
    "                res.append('</b>')\n",
    "                i = j - 1\n",
    "            i += 1\n",
    "        res.append(s[j:])\n",
    "        return \"\".join(res)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        mask = [0] * n\n",
    "        for i in range(n):\n",
    "            prefix = s[i:]\n",
    "            for word in words:\n",
    "                if prefix.startswith(word):\n",
    "                    for j in range(i, min(i + len(word), n)):\n",
    "                        mask[j] = 1\n",
    "        ans = []\n",
    "        for incl, group in itertools.groupby(zip(s, mask), lambda z : z[1]):\n",
    "            if incl == 1:\n",
    "                ans.append('<b>')\n",
    "            ans.append(''.join(z[0] for z in group))\n",
    "            if incl == 1:\n",
    "                ans.append('</b>')\n",
    "        return ''.join(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        bold = [False] * n\n",
    "        # iterate through every index position of string\n",
    "        # for every index position, iterate through every word to check if it is a prefix of current substring, if so, mark is as bolded\n",
    "        for i in range(n):\n",
    "            for w in words:\n",
    "                if s[i:].startswith(w):\n",
    "                    bold[i:i+len(w)] = [True] * len(w)\n",
    "        # combine all the bolded booleans into bold tags\n",
    "        res = \"\"\n",
    "        for i in range(n):\n",
    "            # current position is the start of bold\n",
    "            if bold[i] and (i == 0 or not bold[i-1]):\n",
    "                res += \"<b>\"\n",
    "            res += s[i]\n",
    "            # current position is the end of bold\n",
    "            if bold[i] and (i == n-1 or not bold[i+1]):\n",
    "                res += \"</b>\"\n",
    "        return res\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        N = len(s)\n",
    "        mask = [False] * N\n",
    "        for i in range(N):\n",
    "            prefix = s[i:]\n",
    "            for word in words:\n",
    "                if prefix.startswith(word):\n",
    "                    for j in range(i, min(i+len(word), N)):\n",
    "                        mask[j] = True \n",
    "        \n",
    "        ans = []\n",
    "        for incl, grp in itertools.groupby(zip(s, mask), lambda z: z[1]):\n",
    "            if incl: ans.append(\"<b>\")\n",
    "            \n",
    "            ans.append(\"\".join(z[0] for z in grp))\n",
    "            if incl: ans.append(\"</b>\")\n",
    "        return \"\".join(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        intervals = []\n",
    "        for i in range(len(s)):\n",
    "            for w in words:\n",
    "                if s[i:len(w) + i] == w:\n",
    "                    if intervals:\n",
    "                        l, r = intervals[-1]\n",
    "                        if i <= r + 1:\n",
    "                            intervals[-1][1] = max(len(w)+i-1, r)\n",
    "                            break\n",
    "                    intervals.append([i, len(w)+i-1])\n",
    "        \n",
    "        res = ''\n",
    "        i = j = 0\n",
    "        while i < len(s):\n",
    "            if j < len(intervals):\n",
    "                l,r = intervals[j]\n",
    "                if i < l:\n",
    "                    res += s[i]\n",
    "                    i += 1\n",
    "                else:\n",
    "                    res += '<b>' + s[i : r+1] + '</b>'\n",
    "                    i = r + 1\n",
    "                    j += 1\n",
    "            else:\n",
    "                res += s[i:]\n",
    "                break\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        mask = [0] * n \n",
    "        for i in range(n):\n",
    "            for word in words:\n",
    "                if s[i:].startswith(word):\n",
    "                    mask[i:i + len(word)] = [1] * len(word)\n",
    "        \n",
    "        ans = ''\n",
    "        for i in range(n):\n",
    "            if mask[i] == 1 and (i == 0 or mask[i - 1] == 0):\n",
    "                ans += '<b>'\n",
    "            ans += s[i]\n",
    "            if mask[i] == 1 and (i == n - 1 or mask[i + 1] == 0):\n",
    "                ans += '</b>'\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        n = len(s)\n",
    "        mask = [0] * n\n",
    "        for i in range(n):\n",
    "            for word in words:\n",
    "                if s[i:].startswith(word):\n",
    "                    mask[i:i+len(word)] = [1] * len(word)\n",
    "        res = \"\"\n",
    "        for i in range(n):\n",
    "            if mask[i] == 1 and (i==0 or mask[i-1] == 0):\n",
    "                res += \"<b>\"\n",
    "            res += s[i]\n",
    "            if mask[i] == 1 and (i==n-1 or mask[i+1] == 0):\n",
    "                res += \"</b>\"\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        #区间性判断+模拟\n",
    "        n=len(s)\n",
    "        mask=[False]*n\n",
    "        for word in words:\n",
    "            for i in range(n-len(word)+1):\n",
    "                if s[i:i+len(word)]==word:\n",
    "                    #修改mask,有点差分的味道\n",
    "                    mask[i:i+len(word)]=[True]*len(word)\n",
    "        res=[]\n",
    "        for i in range(n):\n",
    "            if mask[i] and (i==0 or not mask[i-1]):\n",
    "                res.append(\"<b>\")\n",
    "            res.append(s[i])\n",
    "            if mask[i] and (i==n-1 or not mask[i+1]):\n",
    "                res.append(\"</b>\")\n",
    "        return \"\".join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "\n",
    "        starts = [0 for i in range(len(s) + 1)]\n",
    "\n",
    "        def helper(a):\n",
    "            return a[0], -a[1]\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            for w in words:\n",
    "                if i + len(w) <= len(s) and s[i:i+len(w)] == w:\n",
    "                    starts[i] += 1\n",
    "                    starts[i + len(w)] -= 1\n",
    "        \n",
    "        res = \"\"\n",
    "        cur = 0\n",
    "        \n",
    "        i = 0\n",
    "\n",
    "        for i in range(len(starts)):\n",
    "            start = starts[i]\n",
    "            if cur == 0 and start > 0:\n",
    "                res += \"<b>\"\n",
    "            cur += start\n",
    "            if cur == 0 and start < 0:\n",
    "                res += \"</b>\"\n",
    "            if i < len(s):\n",
    "                res += s[i] \n",
    "            \n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        mark=[False]*len(s)\n",
    "        for i in words:\n",
    "            cursor=s.find(i)\n",
    "            while cursor!=-1:\n",
    "                for j in range(cursor,cursor+len(i)):\n",
    "                    mark[j]=True\n",
    "                cursor=s.find(i,cursor+1)\n",
    "        print(mark)\n",
    "        lis=''\n",
    "        for i in range(len(mark)):\n",
    "            if i==0 and mark[0]==True:\n",
    "                lis+='<b>'\n",
    "            if i>0 and mark[i]==True and mark[i-1]==False:\n",
    "                lis+='<b>'\n",
    "            lis+=s[i]\n",
    "            if i==len(s)-1 and mark[i]==True:\n",
    "                lis+='</b>'\n",
    "            if i<len(s)-1 and mark[i]==True and mark[i+1]==False:\n",
    "                lis+='</b>'\n",
    "        return lis"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        mask = [False] * len(s)\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            tmp = s[i:]\n",
    "            for word in words:\n",
    "                if tmp.startswith(word):\n",
    "                    for j in range(i, i + len(word)):\n",
    "                        mask[j] = True\n",
    "        print(mask)\n",
    "        res = []\n",
    "        for flag, pieces in itertools.groupby(zip(s, mask), lambda x: x[1]):\n",
    "            if flag:\n",
    "                res.append('<b>')\n",
    "            res.append(''.join(x[0] for x in pieces))\n",
    "            if flag:\n",
    "                res.append('</b>')\n",
    "            print(res)\n",
    "        res = ''.join(res)\n",
    "        return res\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        s_len = [0 for i in range(len(s))]\n",
    "        # print(s_len)\n",
    "        for word in words:\n",
    "            print(word)\n",
    "            pos = 0\n",
    "            pos_list = []\n",
    "            while pos!=len(s):\n",
    "                p = s[pos:].find(word)\n",
    "                if p==-1:\n",
    "                    break\n",
    "                for i in range(len(word)):\n",
    "                    s_len[pos+p+i] = 1\n",
    "                pos = p+pos+1\n",
    "        print(s_len)\n",
    "        result = \"\"\n",
    "        for i in range(len(s_len)):\n",
    "            if (i==0 and s_len[i]==1 and s_len[i+1]==0) or (i>0 and s_len[i-1]==0 and s_len[i]==1 and s_len[i+1]==0) or (i==len(s_len)-1 and s_len[i]==1 and s_len[i-1]==0):\n",
    "                result += \"<b>\"\n",
    "                result += s[i]\n",
    "                result += \"</b>\"\n",
    "            elif (i==0 and s_len[i]==1) or (i>0 and s_len[i-1]==0 and s_len[i]==1):\n",
    "                result += \"<b>\"\n",
    "                result += s[i]\n",
    "            elif (i==len(s_len)-1 and s_len[i]==1) or (i<len(s_len)-1 and s_len[i+1]==0 and s_len[i]==1):\n",
    "                result += s[i]\n",
    "                result += \"</b>\"\n",
    "            else:\n",
    "                result += s[i]\n",
    "        \n",
    "        print(result)\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        begin = []\n",
    "        end = []\n",
    "        for word in words:\n",
    "            indices = [i for i in range(len(s)) if s.startswith(word, i)]\n",
    "            for start in indices:\n",
    "                begin.append(start)\n",
    "                end.append(start + len(word))\n",
    "        if not begin:\n",
    "            return s\n",
    "        \n",
    "        begin.sort()\n",
    "        end.sort()\n",
    "        # print(begin)\n",
    "        # print(end)\n",
    "\n",
    "        res_interv = []\n",
    "        # merge interv\n",
    "        left, right = begin[0], end[0]\n",
    "        for i in range(1, len(begin)):\n",
    "            if begin[i] <= right:\n",
    "                right = end[i]\n",
    "            else:\n",
    "                res_interv.append([left, right])\n",
    "                # reset \n",
    "                left, right = begin[i], end[i]\n",
    "        res_interv.append([left, right])\n",
    "        #print(res_interv)\n",
    "\n",
    "        # add special token\n",
    "        i = 0\n",
    "        res_str = \"\"\n",
    "        for interv in res_interv:\n",
    "            while i < interv[0]:\n",
    "                res_str += s[i]\n",
    "                i += 1\n",
    "            res_str += '<b>'\n",
    "            sub_len = interv[1] - interv[0]\n",
    "            while sub_len:\n",
    "                res_str += s[i]\n",
    "                sub_len -= 1\n",
    "                i += 1\n",
    "            res_str += '</b>'\n",
    "        # add tail\n",
    "        while i < len(s):\n",
    "            res_str += s[i]\n",
    "            i += 1\n",
    "\n",
    "        return res_str"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        stack = []\n",
    "        n = len(s)\n",
    "        words = set(words)\n",
    "        for i in range(n):\n",
    "            for j in range(i, n):\n",
    "                if s[i:j+1] in words:\n",
    "                    stack.append([i, j])\n",
    "        # print(stack)\n",
    "        final = []\n",
    "        for nums in stack:\n",
    "            if not final or nums[0] > final[-1][1]+1:\n",
    "                final.append(nums)\n",
    "            else:\n",
    "                temp = final.pop()\n",
    "                final.append([temp[0], max(temp[1], nums[1])])\n",
    "        # print(final)\n",
    "        res = ''\n",
    "        pre = 0\n",
    "        for index in final:\n",
    "            res += s[pre:index[0]]\n",
    "            res += '<b>'\n",
    "            res += s[index[0]:index[1]+1]\n",
    "            res += '</b>'\n",
    "            pre = index[1]+1\n",
    "        return res+s[pre:n]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        word_list=[]\n",
    "        for i in range(len(s)):\n",
    "            for j in range(i+1,len(s)+1):\n",
    "                if s[i:j] in words:\n",
    "                    word_list.append([i,j-1])\n",
    "        #区间合并\n",
    "        word_list.sort(key=lambda x:x[0])\n",
    "        print(word_list)\n",
    "        result=[]\n",
    "        if len(word_list)>0:\n",
    "            result.append(word_list[0])\n",
    "        for i in range(1,len(word_list)):\n",
    "            if result[-1][1]>=word_list[i][0]-1:\n",
    "                # print(max(result[-1][1],word_list[i][1]))\n",
    "                result[-1][1]=max(result[-1][1],word_list[i][1])\n",
    "            else:\n",
    "                result.append(word_list[i])\n",
    "        print(result)\n",
    "        count=0\n",
    "        result_str=\"\"\n",
    "        cur=0\n",
    "        while count<len(s):\n",
    "            if cur<len(result) and count==result[cur][0]:\n",
    "                result_str+=\"<b>\"+s[result[cur][0]:result[cur][1]+1]+\"</b>\"\n",
    "                count= result[cur][1]+1\n",
    "                cur+=1\n",
    "\n",
    "            else:\n",
    "                result_str+=s[count]\n",
    "                count+=1\n",
    "        return result_str\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        word_set = set(words)\n",
    "        n = len(s)\n",
    "        lst = []\n",
    "        for i in range(n):\n",
    "            for j in range(i, n):\n",
    "                if s[i:j+1] in word_set:\n",
    "                    lst.append([i, j])\n",
    "        ans = []\n",
    "        for interval in lst:\n",
    "            if not ans or interval[0] > ans[-1][1] + 1:\n",
    "                ans.append(interval)\n",
    "            else:\n",
    "                ans[-1][1] = max(ans[-1][1], interval[1])\n",
    "        starts = set(x[0] for x in ans)\n",
    "        ends = set(x[1] for x in ans)\n",
    "        print(ans)\n",
    "        res = \"\"\n",
    "        for i in range(len(s)):\n",
    "            if i in starts:\n",
    "                res += \"<b>\"\n",
    "            res += s[i]\n",
    "            if i in ends:\n",
    "                res += \"</b>\"\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        len_w = set([len(w) for w in words])\n",
    "        if not words:\n",
    "            return s\n",
    "        words = set(words)\n",
    "\n",
    "        len_s = len(s)\n",
    "        intervals = []\n",
    "\n",
    "        for i in range(len_s):\n",
    "            for d in len_w:\n",
    "                end = i+d\n",
    "                if (end <= len_s) and s[i:end] in words:\n",
    "                    intervals.append((i, end))\n",
    "        \n",
    "        if not intervals:\n",
    "            return s\n",
    "        \n",
    "        # print(intervals)\n",
    "        intervals_marged = []\n",
    "        len_intervals = len(intervals)\n",
    "        idx = 1\n",
    "        start, end = intervals[0]\n",
    "        while idx < len_intervals:\n",
    "            cur_s, cur_e = intervals[idx]\n",
    "            if cur_s <= end:\n",
    "                end = max(cur_e, end)\n",
    "            else:\n",
    "                intervals_marged.append((start, end))\n",
    "                start, end = cur_s, cur_e\n",
    "            idx += 1\n",
    "        intervals_marged.append((start, end))\n",
    "\n",
    "        print(intervals,intervals_marged)\n",
    "        \n",
    "        ans = ''\n",
    "        last_e = 0\n",
    "        for start, end in intervals_marged:\n",
    "            ans += s[last_e:start]\n",
    "            ans += '<b>' + s[start:end] + '</b>'\n",
    "            last_e = end\n",
    "        ans += s[last_e:]\n",
    "\n",
    "        return ans\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        def get_nums():\n",
    "            res = []\n",
    "            res = [[i, i+len(word)] for i in range(len(s)) for word in words if s[i:i+len(word)] == word]\n",
    "            print(res)\n",
    "            res.sort(key=lambda s: s[0])\n",
    "            return res\n",
    "        \n",
    "        def combin_nums(res):\n",
    "            s_stack = []\n",
    "            print(\"res\", res)\n",
    "            for s in res:\n",
    "                if not s_stack: s_stack.append(s)\n",
    "                else:\n",
    "                    print(\"t\", s_stack, s)\n",
    "                    if s_stack[-1][1] < s[0]: s_stack.append(s)\n",
    "                    else:\n",
    "                        s_stack[-1][1] = max(s_stack[-1][1], s[1])\n",
    "            print(s_stack)\n",
    "            return s_stack\n",
    "\n",
    "        get_nums_res = get_nums()\n",
    "        combin_nums_res = combin_nums(get_nums_res)\n",
    "        res = list(s)\n",
    "\n",
    "        for i in combin_nums_res[::-1]:\n",
    "            res.insert(i[1], \"</b>\")\n",
    "            res.insert(i[0], \"<b>\")\n",
    "        return \"\".join(res)\n",
    "            \n",
    "            \n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        def get_nums():\n",
    "            res = []\n",
    "            \n",
    "            res = [[i, i+len(word)] for i in range(len(s)) for word in words if s[i:i+len(word)] == word]\n",
    "            print(res)\n",
    "            res.sort(key=lambda s: s[0])\n",
    "            return res\n",
    "        \n",
    "        def combin_nums(res):\n",
    "            s_stack = []\n",
    "            print(\"res\", res)\n",
    "            for s in res:\n",
    "                if not s_stack: s_stack.append(s)\n",
    "                else:\n",
    "                    print(\"t\", s_stack, s)\n",
    "                    if s_stack[-1][1] < s[0]: s_stack.append(s)\n",
    "                    else:\n",
    "                        s_stack[-1][1] = max(s_stack[-1][1], s[1])\n",
    "            print(s_stack)\n",
    "            return s_stack\n",
    "\n",
    "        get_nums_res = get_nums()\n",
    "        combin_nums_res = combin_nums(get_nums_res)\n",
    "        res = list(s)\n",
    "\n",
    "        for i in combin_nums_res[::-1]:\n",
    "            res.insert(i[1], \"</b>\")\n",
    "            res.insert(i[0], \"<b>\")\n",
    "        return \"\".join(res)\n",
    "            \n",
    "            \n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "\n",
    "        def kmp(s, t):\n",
    "\n",
    "            def get_next(t):\n",
    "                N = len(t)\n",
    "                ans = [0] * N \n",
    "                i, j = 0, 1\n",
    "                while j < N:\n",
    "                    if t[j] == t[i]:\n",
    "                        ans[j] = i+1\n",
    "                        j += 1\n",
    "                    else:\n",
    "                        if i > 0:\n",
    "                            i = ans[i-1]\n",
    "                        else:\n",
    "                            ans[j] = 0\n",
    "                            j += 1\n",
    "                return ans\n",
    "            \n",
    "            next = get_next(t)\n",
    "            i, j = 0, 0\n",
    "            M = len(s)\n",
    "            N = len(t)\n",
    "            ans = []\n",
    "            while i < M:\n",
    "                if s[i] == t[j]:\n",
    "                    if j == N-1:\n",
    "                        ans.append([i-N+1, i])\n",
    "                        j = 0\n",
    "                        i = i-N+2\n",
    "                    else:\n",
    "                        i += 1\n",
    "                        j += 1\n",
    "                else:\n",
    "                    if j > 0:\n",
    "                        j = next[j-1]\n",
    "                    else:\n",
    "                        i += 1\n",
    "            return ans\n",
    "        \n",
    "        candidates = []\n",
    "        for t in words:\n",
    "            candidates.extend(kmp(s, t))\n",
    "        if len(candidates) == 0:\n",
    "            return s \n",
    "        candidates = sorted(candidates, key=lambda x: x[0])\n",
    "        cur = candidates[0]\n",
    "        ans = []\n",
    "        for i in range(1, len(candidates)):\n",
    "            c = candidates[i]\n",
    "            if c[0] > cur[1] + 1:\n",
    "                ans.append([cur[0], cur[1]])\n",
    "                cur = c \n",
    "            else:\n",
    "                cur[1] = max(cur[1], c[1])\n",
    "        ans.append([cur[0], cur[1]])\n",
    "        res = ''\n",
    "        start = 0\n",
    "        for a in ans:\n",
    "            res += s[start:a[0]]\n",
    "            res += '<b>'\n",
    "            res += s[a[0]:a[1]+1]\n",
    "            res += '</b>'\n",
    "            start = a[1] + 1\n",
    "        res += s[start:]\n",
    "        return res\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def get_substring_ranges(self, s, word):\n",
    "        \n",
    "        ans = []\n",
    "        m = len(word)\n",
    "        for i in range(len(s)):\n",
    "            if s[i] != word[0]:\n",
    "                continue\n",
    "            if s[i:i+m] == word:\n",
    "                ans.append([i, i+m])\n",
    "        return ans\n",
    "\n",
    "    def merge_range(self, ranges):\n",
    "        ans = []\n",
    "\n",
    "        ranges.sort(key=lambda x: (x[0], x[1]))\n",
    "        for r in ranges:\n",
    "            if not ans:\n",
    "                ans.append(r)\n",
    "                continue\n",
    "            a = ans.pop()\n",
    "\n",
    "            if r[0] > a[1]:\n",
    "                ans.append(a)\n",
    "                ans.append(r)\n",
    "            else:\n",
    "                ans.append([a[0], max(a[1], r[1])])\n",
    "\n",
    "\n",
    "        return ans\n",
    "\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        ranges = []\n",
    "        for word in words:\n",
    "            ranges += self.get_substring_ranges(s, word)\n",
    "        \n",
    "        merged_ranges = self.merge_range(ranges)\n",
    "\n",
    "        ans = []\n",
    "\n",
    "        bold_string_start = \"<b>\"\n",
    "        bold_string_end = \"</b>\"\n",
    "\n",
    "        index = 0\n",
    "        for r in merged_ranges:\n",
    "            if r[0] != 0:\n",
    "                ans.append(s[index: r[0]])\n",
    "            ans.append(bold_string_start)\n",
    "            ans.append(s[r[0]: r[1]])\n",
    "            ans.append(bold_string_end)\n",
    "            index = r[1]\n",
    "        \n",
    "        if index < len(s):\n",
    "            ans.append(s[index:])\n",
    "        \n",
    "        return \"\".join(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "\n",
    "        starts = []\n",
    "\n",
    "        def helper(a):\n",
    "            return a[0], -a[1]\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            for w in words:\n",
    "                if i + len(w) <= len(s) and s[i:i+len(w)] == w:\n",
    "                    starts.append((i, 1))\n",
    "                    starts.append((i + len(w), -1))\n",
    "        \n",
    "        res = \"\"\n",
    "        cur = 0\n",
    "        starts.sort(key=helper)\n",
    "        \n",
    "        i = 0\n",
    "\n",
    "        for start in starts:\n",
    "            while i < start[0]:\n",
    "                res += s[i]\n",
    "                i += 1\n",
    "\n",
    "            cur += start[1]\n",
    "            if start[1] == 1 and cur == 1:\n",
    "                res += \"<b>\"\n",
    "            elif cur == 0:\n",
    "                res += \"</b>\"\n",
    "        \n",
    "        while i < len(s):\n",
    "            res += s[i]\n",
    "            i += 1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "\n",
    "        starts = []\n",
    "\n",
    "        def helper(a):\n",
    "            return a[0], -a[1]\n",
    "\n",
    "        for i in range(len(s)):\n",
    "            for w in words:\n",
    "                if i + len(w) <= len(s) and s[i:i+len(w)] == w:\n",
    "                    starts.append((i, 1))\n",
    "                    starts.append((i + len(w), -1))\n",
    "        \n",
    "        res = \"\"\n",
    "        cur = 0\n",
    "        starts.sort(key=helper)\n",
    "        print(starts)\n",
    "        i = 0\n",
    "\n",
    "        for start in starts:\n",
    "            while i < start[0]:\n",
    "                res += s[i]\n",
    "                i += 1\n",
    "\n",
    "            cur += start[1]\n",
    "            if start[1] == 1 and cur == 1:\n",
    "                res += \"<b>\"\n",
    "            elif cur == 0:\n",
    "                res += \"</b>\"\n",
    "        \n",
    "        while i < len(s):\n",
    "            res += s[i]\n",
    "            i += 1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addBoldTag(self, s: str, words: List[str]) -> str:\n",
    "        m = {}\n",
    "        for word in words:\n",
    "            for i in range(1, len(word)):\n",
    "                prefix = word[:i]\n",
    "                if prefix not in m:\n",
    "                    m[prefix] = False\n",
    "            m[word] = True\n",
    "\n",
    "        n = len(s)\n",
    "        bold = [False] * n\n",
    "        for i in range(n):\n",
    "            for j in range(i + 1, n + 1):\n",
    "                substr = s[i: j]\n",
    "                if substr not in m:\n",
    "                    break\n",
    "                if m[substr]:\n",
    "                    for k in range(i, j):\n",
    "                        bold[k] = True\n",
    "\n",
    "        ret = ''\n",
    "        inbold = False\n",
    "        for i in range(n):\n",
    "            if bold[i] and not inbold:\n",
    "                ret += '<b>'\n",
    "                inbold = True\n",
    "            elif not bold[i] and inbold:\n",
    "                ret += '</b>'\n",
    "                inbold = False\n",
    "            ret += s[i]\n",
    "        if inbold:\n",
    "            ret += '</b>'\n",
    "        return ret"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while True:\n",
    "            sum = 0\n",
    "            while num!=0:\n",
    "                a = num%10\n",
    "                num = num // 10\n",
    "                sum = sum + a\n",
    "            if sum<10:\n",
    "                return sum\n",
    "                break\n",
    "            else:\n",
    "                num = sum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        result=num\n",
    "        while result >= 10:\n",
    "            result=0\n",
    "            while num >= 10:\n",
    "                result+=num%10\n",
    "                num//=10\n",
    "            else:\n",
    "                result+=num\n",
    "                if result>=10:\n",
    "                    num=result\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        nums=str(num)\n",
    "        n=0\n",
    "        for i in nums:\n",
    "            n+=int(i)\n",
    "            if n >= 10:\n",
    "                n=n%10+1\n",
    "        return n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        return (num -1) % 9 +1 if num else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num>=10:\n",
    "\n",
    "            a = num%10 \n",
    "            b = num//10\n",
    "            num = a+b\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            num = num // 10 + num % 10\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "'''\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        sum = 0\n",
    "        for ele in str(num):\n",
    "            sum = sum + int(ele)\n",
    "        if sum >= 10:\n",
    "            return self.addDigits(sum)\n",
    "        else:\n",
    "            return sum\n",
    "'''\n",
    "'''\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        total_sum = 0\n",
    "        for digit in str(num):\n",
    "            total_sum += int(digit)\n",
    "        if total_sum >= 10:\n",
    "            return self.addDigits(total_sum)\n",
    "        else:\n",
    "            return total_sum\n",
    "'''\n",
    "'''\n",
    "class Solution:\n",
    "    def addDigits(self, num:int) -> int:\n",
    "'''\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num < 10:\n",
    "            return num\n",
    "        ans = 0\n",
    "        while num > 0:\n",
    "            ans += num % 10\n",
    "            num //= 10\n",
    "        return self.addDigits(ans)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            n = num\n",
    "            tmp = 0\n",
    "            while n > 0:\n",
    "                tmp += n % 10\n",
    "                n //= 10\n",
    "            num = tmp \n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        sum = 0\n",
    "        num_str = str(num)\n",
    "        for i in num_str:\n",
    "            sum = sum+int(i)\n",
    "        if len(str(sum))==1:\n",
    "            return sum\n",
    "        else:\n",
    "            return self.addDigits(sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "        while True:\n",
    "            reminder = 0\n",
    "            while num > 0:\n",
    "                reminder += num % 10 \n",
    "                num = num // 10\n",
    "            if reminder // 10 ==0:\n",
    "                return reminder\n",
    "            else:\n",
    "                num = reminder"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "        if num %9 == 0:\n",
    "            return 9\n",
    "        else:\n",
    "            return num%9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num==0:\n",
    "            return 0\n",
    "        if num%9==0:\n",
    "            return 9\n",
    "        return num%9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "        elif num % 9 == 0:\n",
    "            return 9\n",
    "        else:\n",
    "            return num % 9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            su = 0\n",
    "            while num:\n",
    "                su += num % 10\n",
    "                num //= 10\n",
    "            num = su\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if (num)<10:\n",
    "            return num\n",
    "        while 1:\n",
    "            theSum = num//10 + num%10\n",
    "            if theSum > 9:\n",
    "                num = num//10 + num%10\n",
    "            else:\n",
    "                return theSum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "        res = num % 9\n",
    "        if res == 0:\n",
    "            res = 9\n",
    "        return res\n",
    "\n",
    "        p = str(num)\n",
    "        while len(p) > 1:\n",
    "            pn = sum([int(i) for i in p])\n",
    "            p = str(pn)\n",
    "        return int(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            num = sum(map(int, str(num)))\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "\n",
    "\n",
    "        # 拆分相加函数\n",
    "        def helper(n):\n",
    "            # list = [] \n",
    "            # while n > 0:\n",
    "            #     cur = n % 10\n",
    "            #     list.append(cur)\n",
    "            #     n //= 10\n",
    "            # return sum(list)\n",
    "        # print(helper(num))\n",
    "            sum = 0\n",
    "            while n > 0:\n",
    "                sum += n % 10\n",
    "                n //= 10\n",
    "            return sum\n",
    "\n",
    "        while num >= 10:\n",
    "            num = helper(num)\n",
    "        return num\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        count = 9999999999\n",
    "        while count > 0 and num >= 10:\n",
    "            for i in range(len(str(num))-1):\n",
    "                num = sum(int(char) for char in str(num))\n",
    "                count -= 1\n",
    "\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:   \n",
    "        c = 0\n",
    "        while (num != 0):\n",
    "            b = num % 10\n",
    "            c = c + b\n",
    "            num = int (num / 10)\n",
    "            if (c > 9):\n",
    "                num += c\n",
    "                c = 0\n",
    "            if (c < 10 and num == 0):\n",
    "                break\n",
    "        return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num < 10:\n",
    "            return num\n",
    "        s = 0\n",
    "        while num:\n",
    "            s += num % 10\n",
    "            num //= 10\n",
    "        return self.addDigits(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            res = 0\n",
    "            for i in str(num):\n",
    "                res += int(i)\n",
    "            num = res\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        return 1 + (num - 1) % 9 if num else 0\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        s=str(num)\n",
    "        while len(s)!=1:\n",
    "            s=str(sum(int(i) for i in s))\n",
    "        return int(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num > 9:\n",
    "            num = sum(list(map(int, list(str(num)))))\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        sum = 0\n",
    "        while(num>0):\n",
    "            sum+=num%10\n",
    "            num=int(num/10)\n",
    "        if sum < 10:\n",
    "            return sum\n",
    "        else:\n",
    "            return self.addDigits(sum)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "        while num > 9:\n",
    "            s = str(num)\n",
    "            num = 0\n",
    "            for i in s:\n",
    "                num += int(i)\n",
    "        else:\n",
    "            return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        p = str(num)\n",
    "        while len(p) > 1:\n",
    "            pn = sum([int(i) for i in p])\n",
    "            p = str(pn)\n",
    "        return int(p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        x=num%10+num//10\n",
    "        while x>=10:\n",
    "            x=x%10+x//10\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        def Extractdigit(num):\n",
    "            ans=0\n",
    "            while num > 0:\n",
    "                digit = num % 10\n",
    "                num = num // 10\n",
    "                ans+=digit\n",
    "            return ans\n",
    "\n",
    "        if num<10:\n",
    "            return num\n",
    "        else:\n",
    "            while num >= 10:\n",
    "                num=Extractdigit(num)\n",
    "            return num\n",
    "\n",
    "\n",
    "            \n",
    "        \n",
    "\n",
    "       \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num==0:\n",
    "            return 0\n",
    "        return 9 if num%9==0 else num%9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        s=0\n",
    "        while num>=10:\n",
    "            b=int(num%10)\n",
    "            s+=b\n",
    "            num=int(num/10)\n",
    "        while num<10:\n",
    "            s+=num\n",
    "            while(s>=10):\n",
    "                s=int(s/10)+s%10\n",
    "            return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "\n",
    "        while len(str(num)) != 1:\n",
    "            new_num = 0\n",
    "            for i in str(num):\n",
    "                new_num += int(i)\n",
    "\n",
    "            num = new_num\n",
    "\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while   num >= 10 :\n",
    "            a = num % 10\n",
    "            b = num  // 10\n",
    "            num = a + b\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num>=10:\n",
    "            sum=0\n",
    "            while num:\n",
    "                sum+=num%10\n",
    "                num//=10\n",
    "            num=sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "      return 9 if (num % 9 == 0) and (num != 0) else num % 9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while True:\n",
    "            if num//10==0:\n",
    "                return num\n",
    "            num=sum(int(i) for i in list(str(num)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num < 10:\n",
    "            return num\n",
    "        def add(x):\n",
    "            res = 0\n",
    "            while x > 0:\n",
    "                res += x % 10\n",
    "                x //= 10\n",
    "            return res\n",
    "\n",
    "        while num >= 10:\n",
    "            if num % 10 == 0:\n",
    "                num //= 10\n",
    "            else:\n",
    "                num = add(num)\n",
    "        return num\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        count = num\n",
    "        while len(str(count)) > 1:\n",
    "            num = count\n",
    "            count = 0\n",
    "            while num > 0:\n",
    "                count += num % 10\n",
    "                num //= 10\n",
    "        return count\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while len(str(num)) != 1:\n",
    "            l = [0 for i in range(0, len(str(num)))]\n",
    "            for i in range(0, len(str(num))):\n",
    "                l[i] = int(str(num)[i])\n",
    "            num = sum(l)\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num > 9:\n",
    "            s = str(num)\n",
    "            num = 0\n",
    "            for i in s:\n",
    "                num += int(i)\n",
    "        else:\n",
    "            return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num < 10:\n",
    "            return num\n",
    "        \n",
    "        _num = 0\n",
    "        while num > 0:\n",
    "            _num += num % 10\n",
    "            num //= 10\n",
    "        return self.addDigits(_num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            l = list(str(num))\n",
    "            num = 0\n",
    "            for i in l:\n",
    "                num += int(i)\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        x=num%10+num//10\n",
    "        while x>=10:\n",
    "            x=x%10+x//10\n",
    "        return x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        \n",
    "       \n",
    "        while True:\n",
    "            temp=0\n",
    "            while (num>0):\n",
    "                temp=temp+num%10\n",
    "                num=num//10\n",
    "            if temp>=10:\n",
    "                num=temp\n",
    "            else:\n",
    "                return temp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        # 模拟\n",
    "        if num == 0:\n",
    "            return 0\n",
    "            \n",
    "        def helper(num):\n",
    "            res = 0\n",
    "            while num:\n",
    "                x = num % 10  # 取得最后一位数\n",
    "                res += x\n",
    "                num //= 10\n",
    "            return res\n",
    "        while num:\n",
    "            num = helper(num)\n",
    "            if 0 < num < 10:\n",
    "                return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def addDigits(self, num: int) -> int:\r\n",
    "        # if num < 10:\r\n",
    "        #     return num\r\n",
    "        # s = str(num)\r\n",
    "        # res = 0\r\n",
    "        # for c in s: res += int(c)\r\n",
    "        # return self.addDigits(res)\r\n",
    "        # while num >= 10:\r\n",
    "        #     sum = 0\r\n",
    "        #     while num:\r\n",
    "        #         sum += num % 10\r\n",
    "        #         num //= 10\r\n",
    "        #     num = sum\r\n",
    "        # return num\r\n",
    "        return (num - 1) % 9 + 1 if num else 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num // 10 == 0:\n",
    "            return num\n",
    "        \n",
    "        total = num % 10\n",
    "        while num // 10 > 0:\n",
    "            num //= 10\n",
    "            total += (num % 10)\n",
    "        \n",
    "        return self.addDigits(total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        def jia(num):\n",
    "            sum = 0\n",
    "            while num>0:\n",
    "                sum += num%10\n",
    "                num = num//10\n",
    "            return sum\n",
    "        while num>9:\n",
    "            num = jia(num)\n",
    "        return num\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        def w(n):\n",
    "            res = 0\n",
    "            while n:\n",
    "                res += n % 10\n",
    "                n //= 10\n",
    "            return res\n",
    "        def rs(n):\n",
    "            if len(str(n)) == 1:\n",
    "                return n\n",
    "            return rs(w(n))\n",
    "        return rs(num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def addDigits(self, num: int) -> int:\r\n",
    "        # if num < 10:\r\n",
    "        #     return num\r\n",
    "        # s = str(num)\r\n",
    "        # res = 0\r\n",
    "        # for c in s: res += int(c)\r\n",
    "        # return self.addDigits(res)\r\n",
    "        while num >= 10:\r\n",
    "            sum = 0\r\n",
    "            while num:\r\n",
    "                sum += num % 10\r\n",
    "                num //= 10\r\n",
    "            num = sum\r\n",
    "        return num\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            num = sum(map(int, str(num)))\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while   num >= 10 :\n",
    "            a = num % 10\n",
    "            b = num  // 10\n",
    "            num = a + b\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num // 10 == 0:\n",
    "            return num\n",
    "        \n",
    "        total = num % 10\n",
    "        while num // 10 > 0:\n",
    "            num //= 10\n",
    "            total += (num % 10)\n",
    "        \n",
    "        return self.addDigits(total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        return (num - 1) % 9 + 1 if num else num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        res = num\n",
    "        while res >= 10:\n",
    "            new_res = 0\n",
    "            res_str = str(res)\n",
    "            for c in res_str:\n",
    "                new_res += int(c)\n",
    "            res = new_res\n",
    "        return res\n",
    "\n",
    "\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        if num == 0:\n",
    "            return 0\n",
    "        elif num % 9 != 0:\n",
    "            return num % 9\n",
    "        else:\n",
    "            return 9"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num >= 10:\n",
    "            sum = 0\n",
    "            while num:\n",
    "                sum += num % 10\n",
    "                num //= 10\n",
    "            num = sum\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addDigits(self, num: int) -> int:\n",
    "        while num>9:\n",
    "            sum=0\n",
    "            while num:\n",
    "                sum+=num%10\n",
    "                num=num//10\n",
    "            num=sum\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        degrees = [0]*(n+1)\n",
    "        for a, b in edges:\n",
    "            degrees[a] += 1\n",
    "            degrees[b] += 1\n",
    "        singles = set()\n",
    "        for i, v in enumerate(degrees[1:], 1):\n",
    "            if v & 1:\n",
    "                singles.add(i)\n",
    "        NS = len(singles)\n",
    "        if not NS: return True\n",
    "        if NS > 4 or NS & 1: return False\n",
    "        if NS == 2:\n",
    "            nexts = defaultdict(set)\n",
    "            for a, b in edges:\n",
    "                if a in singles:\n",
    "                    nexts[a].add(b)\n",
    "                if b in singles:\n",
    "                    nexts[b].add(a)\n",
    "            return not (singles & next(iter(nexts.values()))) or n > len(reduce(or_, (nexts[v] for v in singles), singles))\n",
    "        c = Counter()\n",
    "        for a, b in edges:\n",
    "            if a in singles and b in singles:\n",
    "                c[a] += 1\n",
    "                c[b] += 1\n",
    "        cc = Counter(c.values())        \n",
    "        return cc[3] == 0 and cc[2] != 3\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = [0 for _ in range(n)]\n",
    "        odd,even = [],[]\n",
    "        s = set()\n",
    "        for u,v in edges:\n",
    "            g[u-1]+=1\n",
    "            g[v-1]+=1\n",
    "            s.add((u,v))\n",
    "        for i in range(n):\n",
    "            if g[i]%2==1:\n",
    "                odd.append(i+1)\n",
    "            else:\n",
    "                even.append(i+1)\n",
    "        if not odd:\n",
    "            return True\n",
    "        elif len(odd)==2:\n",
    "            if ((odd[0],odd[1]) not in s) and ((odd[1],odd[0]) not in s):\n",
    "                return True\n",
    "            else:\n",
    "                for node in range(1,n+1):\n",
    "                    if node==odd[0] or node==odd[1]:\n",
    "                        continue\n",
    "                    else:\n",
    "                        if (((node,odd[0]) not in s) and ((odd[0],node) not in s)) and (((node,odd[1]) not in s) and ((odd[1],node) not in s)):\n",
    "                            return True\n",
    "                return False\n",
    "        elif len(odd)==4:\n",
    "            dic = [0,0,0,0]\n",
    "            for i in range(4):\n",
    "                for j in range(i+1,4):\n",
    "                    if (odd[i],odd[j]) in s or (odd[j],odd[i]) in s:\n",
    "                        dic[i]+=1\n",
    "                        dic[j]+=1\n",
    "                        if dic[i]>=3 or dic[j]>=3:\n",
    "                            return False\n",
    "            if sorted(dic)==[0,2,2,2]:\n",
    "                return False\n",
    "            else:\n",
    "                return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = [0 for _ in range(n)]\n",
    "        odd,even = [],[]\n",
    "        s = set()\n",
    "        for u,v in edges:\n",
    "            g[u-1]+=1\n",
    "            g[v-1]+=1\n",
    "            s.add((u,v))\n",
    "        for i in range(n):\n",
    "            if g[i]%2==1:\n",
    "                odd.append(i+1)\n",
    "            else:\n",
    "                even.append(i+1)\n",
    "        if not odd:\n",
    "            return True\n",
    "        elif len(odd)==2:\n",
    "            if ((odd[0],odd[1]) not in s) and ((odd[1],odd[0]) not in s):\n",
    "                return True\n",
    "            else:\n",
    "                for node in range(1,n+1):\n",
    "                    if node==odd[0] or node==odd[1]:\n",
    "                        continue\n",
    "                    else:\n",
    "                        if (((node,odd[0]) not in s) and ((odd[0],node) not in s)) and (((node,odd[1]) not in s) and ((odd[1],node) not in s)):\n",
    "                            return True\n",
    "                return False\n",
    "        elif len(odd)==4:\n",
    "            dic = [0,0,0,0]\n",
    "            for i in range(4):\n",
    "                for j in range(i+1,4):\n",
    "                    if (odd[i],odd[j]) in s or (odd[j],odd[i]) in s:\n",
    "                        dic[i]+=1\n",
    "                        dic[j]+=1\n",
    "                        if dic[i]>=3 or dic[j]>=3:\n",
    "                            return False\n",
    "            if sorted(dic)==[0,2,2,2]:\n",
    "                return False\n",
    "            else:\n",
    "                return True\n",
    "        else:\n",
    "            return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from collections import defaultdict\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i,nb in g.items() if len(nb) %2]\n",
    "        m = len(odd)\n",
    "        if m==0: return True\n",
    "\n",
    "        if m==2:\n",
    "            x,y = odd\n",
    "            return x not in g[y] or any(i != x and i != y and x not in g[i] and y not in g[i] \n",
    "                                        for i in range(1,n+1))\n",
    "        if m==4:\n",
    "            a,b,c,d = odd\n",
    "            return  b not in g[a] and d not in g[c] or \\\n",
    "                    c not in g[a] and d not in g[b] or \\\n",
    "                    d not in g[a] and c not in g[b]\n",
    "        \n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2] # 获取每个节点度数\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0:\n",
    "            return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(i != x and i != y and x not in g[i] and y not in g[i] for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or c not in g[a] and d not in g[b] or d not in g[a] and c not in g[b]\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        edge = defaultdict(set)\n",
    "        for i,j in edges:\n",
    "            edge[i].add(j)\n",
    "            edge[j].add(i)\n",
    "        point=[item[0] for item in edge.items() if len(item[1])%2 ==1]\n",
    "        if len(point) == 0:\n",
    "            return True\n",
    "        elif len(point) == 2:\n",
    "            if point[0]not in edge[point[1]]:\n",
    "                return True\n",
    "            else:\n",
    "                for k in range(1,n):\n",
    "                    if (k!=point[0] and k!=point[1]) and (k not in edge[point[0]] and k not in edge[point[1]]):\n",
    "                        return True\n",
    "                return False\n",
    "        elif len(point)==4: \n",
    "            if (point[0] not in edge[point[1]] and point[2] not in edge[point[3]])or\\\n",
    "            (point[0]not in edge[point[2]] and point[1] not in edge[point[3]])or\\\n",
    "            (point[0]not in edge[point[3]] and point[1] not in edge[point[2]]):\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "                \n",
    "        else: return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        edge = defaultdict(set)\n",
    "        point = []\n",
    "        for i,j in edges:\n",
    "            edge[i].add(j)\n",
    "            edge[j].add(i)\n",
    "        for item in edge.items():\n",
    "            if len(item[1])%2 == 1:\n",
    "                point.append(item[0])\n",
    "        if len(point) == 0:\n",
    "            return True\n",
    "        elif len(point) == 2:\n",
    "            if point[0]not in edge[point[1]]:\n",
    "                return True\n",
    "            else:\n",
    "                for k in range(1,n):\n",
    "                    if (k!=point[0] and k!=point[1]) and (k not in edge[point[0]] and k not in edge[point[1]]):\n",
    "                        return True\n",
    "                return False\n",
    "        elif len(point)==4: \n",
    "            if (point[0] not in edge[point[1]] and point[2] not in edge[point[3]])or\\\n",
    "            (point[0]not in edge[point[2]] and point[1] not in edge[point[3]])or\\\n",
    "            (point[0]not in edge[point[3]] and point[1] not in edge[point[2]]):\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "                \n",
    "        else: return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        graph = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            graph[x].add(y)\n",
    "            graph[y].add(x)\n",
    "        odds = set()\n",
    "        for node in graph.keys():\n",
    "            if graph[node].__len__()%2==1:\n",
    "                odds.add(node)\n",
    "        m = len(odds)\n",
    "        odds = list(odds)\n",
    "        if m==0:\n",
    "            return True\n",
    "        if m == 2:\n",
    "            a, b = odds[0], odds[1]\n",
    "            if a not in graph[b]:\n",
    "                return True\n",
    "            for node in range(1, n+1):\n",
    "                if node == a or node==b:\n",
    "                    continue\n",
    "                if node not in graph[a] and node not in graph[b]:\n",
    "                    return True\n",
    "            return False\n",
    "        if m == 4:\n",
    "            a, b, c, d = odds\n",
    "            return (a not in graph[b] and c not in graph[d]) | \\\n",
    "                    (a not in graph[c] and b not in graph[d]) | \\\n",
    "                    (a not in graph[d] and c not in graph[b])\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        # build adjacency list of undirected graph\n",
    "        g = defaultdict(set)\n",
    "        for u, v in edges:\n",
    "            g[u].add(v)\n",
    "            g[v].add(u)\n",
    "        \n",
    "        # find vertices with odds degree\n",
    "        odds = [u for u in g if len(g[u]) % 2]\n",
    "\n",
    "        # number of vertices with odds degree\n",
    "        m = len(odds)\n",
    "        if m == 0: \n",
    "            # connect nothing\n",
    "            return True\n",
    "        if m == 2:\n",
    "            u, v = odds\n",
    "            # connect 1 edge: u-v\n",
    "            if u not in g[v]:\n",
    "                return True \n",
    "            else:\n",
    "                for i in range(1, n + 1):\n",
    "                    # connect 2 edges: edge i-u and edge i-v\n",
    "                    if i not in {u, v} and u not in g[i] and v not in g[i]:\n",
    "                        return True \n",
    "\n",
    "        # connect 2 edges\n",
    "        # 1. edge a-b and edge c-d\n",
    "        # 2. edge a-c and edge b-d\n",
    "        # 3. edge a-d and edge b-c                \n",
    "        if m == 4:\n",
    "            a, b, c, d = odds\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        \n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2: \n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(i != x and i != y and x not in g[i] and y not in g[i]\n",
    "            for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd \n",
    "            return (b not in g[a] and d not in g[c]) or \\\n",
    "                   (c not in g[a] and d not in g[b]) or \\\n",
    "                   (d not in g[a] and c not in g[b]) \n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import List\n",
    "from collections import defaultdict\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        \n",
    "        if m == 0:\n",
    "            return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = [i for i, nb in g.items() if len(nb) % 2]\n",
    "        m = len(odd)\n",
    "        if m == 0: return True\n",
    "        if m == 2:\n",
    "            x, y = odd\n",
    "            return x not in g[y] or any(\n",
    "                i != x and i != y and x not in g[i] and y not in g[i]\n",
    "                for i in range(1, n + 1))\n",
    "        if m == 4:\n",
    "            a, b, c, d = odd\n",
    "            return b not in g[a] and d not in g[c] or \\\n",
    "                   c not in g[a] and d not in g[b] or \\\n",
    "                   d not in g[a] and c not in g[b]\n",
    "        return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addEdges(self, n: int, edges: List[List[int]],edge: List[int]) -> bool:\n",
    "        dic = {}\n",
    "        edges.append(edge)\n",
    "        for ii in range(n):\n",
    "            dic[ii+1] = 0\n",
    "        for edge in edges:\n",
    "            dic[edge[0]] += 1\n",
    "            dic[edge[1]] += 1\n",
    "        \n",
    "        verticeOdd = []\n",
    "        for key,value in dic.items():\n",
    "            if value%2 ==1:\n",
    "                verticeOdd.append(key)\n",
    "        if len(verticeOdd) == 0:\n",
    "            return True\n",
    "        return False\n",
    "\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        dic = {}\n",
    "        for ii in range(n):\n",
    "            dic[ii+1] = 0\n",
    "        for ii,edge in enumerate(edges):\n",
    "            if edge[0]>edge[1]:\n",
    "                edges[ii] = [edge[1],edge[0]]\n",
    "            dic[edge[0]] += 1\n",
    "            dic[edge[1]] += 1\n",
    "        \n",
    "        verticeOdd = []\n",
    "        for key,value in dic.items():\n",
    "            if value%2 ==1:\n",
    "                verticeOdd.append(key)\n",
    "        m = len(verticeOdd)\n",
    "        if m == 0:\n",
    "            return True\n",
    "        if m not in [2,4]:\n",
    "            return False\n",
    "\n",
    "\n",
    "        flag = 0\n",
    "        for vi in verticeOdd:\n",
    "            for vj in verticeOdd:\n",
    "                edgeTmp = [vi,vj]\n",
    "                if vj>vi and edgeTmp not in edges:\n",
    "                    edges2 = edges[:]\n",
    "                    flag = self.addEdges(n,edges2,edgeTmp)\n",
    "                    if flag == 1:\n",
    "                        return True\n",
    "                    if m==4:\n",
    "                        edgesTmp = edges[:]\n",
    "                        edgesTmp.append(edgeTmp)\n",
    "                        edgeC = verticeOdd[:]\n",
    "                        edgeC.remove(vi)\n",
    "                        edgeC.remove(vj)\n",
    "                        if edgeC not in edges:\n",
    "                            flag = self.addEdges(n,edgesTmp,edgeC)\n",
    "                            if flag == 1:\n",
    "                                return True\n",
    "        if m==2:\n",
    "            #construct dictionary of odd\n",
    "            dicOdd = {}\n",
    "            v1 = verticeOdd[0]\n",
    "            v2 = verticeOdd[1]\n",
    "            dicOdd[v1]=set()\n",
    "            dicOdd[v2]=set()\n",
    "            for edge in edges:\n",
    "                if edge[0]==v1:\n",
    "                    dicOdd[v1].add(edge[1])\n",
    "                if edge[1]==v1:\n",
    "                    dicOdd[v1].add(edge[0])\n",
    "                if edge[0]==v2:\n",
    "                    dicOdd[v2].add(edge[1])\n",
    "                if edge[1]==v2:\n",
    "                    dicOdd[v2].add(edge[0])\n",
    "            for vi in range(1,n+1):\n",
    "                if vi not in verticeOdd and vi not in dicOdd[v1] and vi not in dicOdd[v2]:\n",
    "                    if vi<v1:\n",
    "                        edge1 = [vi,v1]\n",
    "                    else:\n",
    "                        edge1 = [v1,vi]\n",
    "                    if vi<v2:\n",
    "                        edge2 = [vi,v2]\n",
    "                    else:\n",
    "                        edge2 = [v2,vi]\n",
    "                    edges2 = edges[:]\n",
    "                    edges2.append(edge1)\n",
    "                    flag = self.addEdges(n,edges2,edge2)\n",
    "                    if flag == 1:\n",
    "                        return True\n",
    "        \n",
    "        return False\n",
    "        \n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = defaultdict(set)\n",
    "        d = Counter()\n",
    "        for a, b in edges:\n",
    "            g[a].add(b)\n",
    "            g[b].add(a)\n",
    "            d[a] += 1\n",
    "            d[b] += 1\n",
    "            \n",
    "        p = [i for i, x in d.items() if x % 2]\n",
    "        x = len(p)\n",
    "        if x == 0: return True\n",
    "        if x == 2:\n",
    "            a, b = p \n",
    "            if a not in g[b] and b not in g[a]: return True\n",
    "            for j in range(1, n+1):\n",
    "                if j != a and j != b and j not in g[a] and j not in g[b]:\n",
    "                    return True\n",
    "            return False\n",
    "        if x == 4:\n",
    "            a, b, c, d = p \n",
    "            return a not in g[b] and c not in g[d] or \\\n",
    "                   a not in g[c] and b not in g[d] or \\\n",
    "                   a not in g[d] and b not in g[c]\n",
    "        return False    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        deg = [set() for _ in range(n + 1)]\n",
    "\n",
    "        for i, j in edges:\n",
    "            deg[i].add(j)\n",
    "            deg[j].add(i)\n",
    "\n",
    "        nodes = []\n",
    "        for idx, i in enumerate(deg):\n",
    "            if len(i) % 2:\n",
    "                nodes.append(idx)\n",
    "        \n",
    "        print(nodes)\n",
    "        if len(nodes) == 0:\n",
    "            return True\n",
    "        if len(nodes) == 2:\n",
    "            return n != len(deg[nodes[0]] | deg[nodes[1]])\n",
    "        if len(nodes) == 4:\n",
    "            a, b, c, d = nodes\n",
    "            sols = [[(a, c), (b, d)], [(a, b), (c, d)], [(a, d), (b, c)]]\n",
    "            for x, y in sols:\n",
    "                if (not x[0] in deg[x[1]]) and (not y[0] in deg[y[1]]):\n",
    "                    return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        deg = [0] * (n + 1)\n",
    "        s = set()\n",
    "        for i, j in edges:\n",
    "            deg[i] += 1\n",
    "            deg[j] += 1\n",
    "            s.add((i, j))\n",
    "            s.add((j, i))\n",
    "        odd = []\n",
    "        for i in range(1, n + 1):\n",
    "            if deg[i] % 2 == 1:\n",
    "                odd.append(i)\n",
    "        if len(odd) == 0:\n",
    "            return True\n",
    "        if len(odd) == 2:\n",
    "            i, j = odd[0], odd[1]\n",
    "            if (i, j) not in s:\n",
    "                return True\n",
    "            for k in range(1, n + 1):\n",
    "                if k == i or k == j:\n",
    "                    continue\n",
    "                if (i, k) not in s and (k, j) not in s:\n",
    "                    return True\n",
    "        if len(odd) == 4:\n",
    "            a, b, c, d = odd[0], odd[1], odd[2], odd[3]\n",
    "            if (a, b) not in s and (c, d) not in s:\n",
    "                return True\n",
    "            if (a, c) not in s and (b, d) not in s:\n",
    "                return True\n",
    "            if (a, d) not in s and (b, c) not in s:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        deg = [0] * (n + 1)\n",
    "        g = [set() for _ in range(n + 1)]\n",
    "        for a, b in edges:\n",
    "            # if (a == 2 and b == 3) or (a == 3 and b == 2)\n",
    "            deg[a] += 1\n",
    "            deg[b] += 1\n",
    "            g[a].add(b)\n",
    "            g[b].add(a)\n",
    "        cnt = 0\n",
    "        d = []\n",
    "        for i in range(n + 1):\n",
    "            if deg[i] & 1:\n",
    "                d.append(i)\n",
    "        # print(d)\n",
    "        if len(d) == 0:\n",
    "            return True\n",
    "        if len(d) == 2:\n",
    "            if d[0] not in g[d[1]]:\n",
    "                return True\n",
    "            for i in range(1, n + 1):\n",
    "                if i not in d and i not in g[d[0]] and i not in g[d[1]]:\n",
    "                    return True\n",
    "            return False\n",
    "        if len(d) > 4:\n",
    "            return False\n",
    "        n1, n2, n3, n4 = d\n",
    "        if n1 not in g[n2] and n3 not in g[n4]:\n",
    "            return True\n",
    "        if n1 not in g[n3] and n2 not in g[n4]:\n",
    "            return True\n",
    "        if n1 not in g[n4] and n2 not in g[n3]:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        deg = [0] * n\n",
    "        g = defaultdict(set)\n",
    "        for x, y in edges:\n",
    "            x, y = x - 1, y - 1\n",
    "            deg[x] += 1\n",
    "            deg[y] += 1\n",
    "            g[x].add(y)\n",
    "            g[y].add(x)\n",
    "        odd = set()\n",
    "        for i in range(n):\n",
    "            if deg[i] & 1:\n",
    "                odd.add(i)\n",
    "        if len(odd) & 1 or len(odd) > 4: return False\n",
    "        if not len(odd): return True\n",
    "        if len(odd) == 2:\n",
    "            a, b = odd\n",
    "            if b not in g[a]: return True\n",
    "            for i in range(n):\n",
    "                if i != a and i != b and a not in g[i] and b not in g[i]:\n",
    "                    return True\n",
    "        else:\n",
    "            for x, y in permutations(odd, 2):\n",
    "                a, b = odd - set([x, y])\n",
    "                if x not in g[y] and a not in g[b]: return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        s = set()\n",
    "        d = [0] * (n + 1)\n",
    "        for x, y in edges:\n",
    "            d[x] += 1\n",
    "            d[y] += 1\n",
    "            s.add((x, y))\n",
    "            s.add((y, x))\n",
    "        \n",
    "        odd = list()\n",
    "        even = list()\n",
    "        for i in range(1, n + 1):\n",
    "            if d[i] & 1:\n",
    "                odd.append(i)\n",
    "            else:\n",
    "                even.append(i)\n",
    "        \n",
    "        if len(odd) == 0:\n",
    "            return True\n",
    "        if len(odd) == 2:\n",
    "            x, y = odd\n",
    "            if (x, y) not in s:\n",
    "                return True\n",
    "            for cand in even:\n",
    "                if (x, cand) not in s and (y, cand) not in s:\n",
    "                    return True\n",
    "            return False\n",
    "        if len(odd) == 4:\n",
    "            a, b, c, d = odd\n",
    "            if (a, b) not in s and (c, d) not in s:\n",
    "                return True\n",
    "            if (a, c) not in s and (b, d) not in s:\n",
    "                return True\n",
    "            if (a, d) not in s and (b, c) not in s:\n",
    "                return True\n",
    "            return False\n",
    "        return False\n",
    "        \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "from typing import *\n",
    "from math import *\n",
    "from functools import cache\n",
    "from queue import *\n",
    "from heapq import *\n",
    "\n",
    "# start-----------------------------------------------------\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        deg = [0] * (n + 1)\n",
    "        g = [set() for _ in range(n + 1)] \n",
    "        for u,v in edges:\n",
    "            deg[u] += 1\n",
    "            deg[v] += 1\n",
    "            g[u].add(v)\n",
    "            g[v].add(u)\n",
    "        z = []\n",
    "        p = []\n",
    "        for i,d in enumerate(deg):\n",
    "            if d & 1:\n",
    "                z.append(i)\n",
    "            else:\n",
    "                p.append(i)\n",
    "        p = p[1:]\n",
    "        m = len(z)\n",
    "        if m & 1:\n",
    "            return False\n",
    "        if m > 4:\n",
    "            return False\n",
    "        if m == 0:\n",
    "            return True\n",
    "        k = []\n",
    "        for u in z:\n",
    "            for v in z:\n",
    "                if u == v:\n",
    "                    continue\n",
    "                if v not in g[u]:\n",
    "                    k.append((u,v))\n",
    "        if m == 2:\n",
    "            if len(k):\n",
    "                return True\n",
    "            else:\n",
    "                for u in p:\n",
    "                    for v in z:\n",
    "                        if v in g[u]:\n",
    "                            break\n",
    "                    else:\n",
    "                        return True\n",
    "                return False\n",
    "        for a in k:\n",
    "            for b in k:\n",
    "                if a == b:\n",
    "                    continue\n",
    "                if a[0] != b[0] and a[0] != b[1] and a[1] != b[0] and a[1] != b[1]:\n",
    "                    return True\n",
    "        return False\n",
    "s = Solution()\n",
    "s.isPossible(4,[[1,2],[2,3],[2,4],[3,4]])\n",
    "# end-------------------------------------------------------"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        g = [set() for _ in range(n)]\n",
    "        for a, b in edges:\n",
    "            g[a-1].add(b-1)\n",
    "            g[b-1].add(a-1)\n",
    "        count = []\n",
    "        for i in range(n):\n",
    "            if len(g[i]) == n-1 and not n % 2:\n",
    "                return False\n",
    "            if len(g[i]) % 2:\n",
    "                count.append(i)\n",
    "        lc = len(count)\n",
    "        if lc > 4:\n",
    "            return False\n",
    "        if lc == 0:\n",
    "            return True\n",
    "        if lc == 2:\n",
    "            a, b = count\n",
    "            for i in range(n):\n",
    "                if a not in g[i] and b not in g[i]:\n",
    "                    return True\n",
    "            return False\n",
    "        a, b, c, d = count\n",
    "        if a not in g[b] and c not in g[d]:\n",
    "            return True\n",
    "        if a not in g[c] and b not in g[d]:\n",
    "            return True\n",
    "        if a not in g[d] and b not in g[c]:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        node = [set() for _ in range(n)]\n",
    "        for x, y in edges:\n",
    "            node[x-1].add(y-1)\n",
    "            node[y-1].add(x-1)\n",
    "        \n",
    "        nodeSet = []\n",
    "        for i in range(n):\n",
    "            if len(node[i]) % 2 == 1:   nodeSet.append(i)\n",
    "        \n",
    "        if len(nodeSet) == 0:   return True\n",
    "        if len(nodeSet) == 2:\n",
    "            if nodeSet[0] not in node[nodeSet[1]]:  return True\n",
    "            for x in range(n):\n",
    "                if x not in nodeSet and x not in node[nodeSet[0]] and x not in node[nodeSet[1]]:    return True\n",
    "        if len(nodeSet) == 4:\n",
    "            nodePair = [[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 1, 2]]\n",
    "            for A, B, C, D in nodePair:\n",
    "                if nodeSet[A] not in node[nodeSet[B]] and nodeSet[C] not in node[nodeSet[D]]:   return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        node = [set() for _ in range(n)]\n",
    "        for x, y in edges:\n",
    "            node[x-1].add(y-1)\n",
    "            node[y-1].add(x-1)\n",
    "        \n",
    "        nodeSet = []\n",
    "        for i in range(n):\n",
    "            if len(node[i]) % 2 == 1:   nodeSet.append(i)\n",
    "        \n",
    "        if len(nodeSet) == 0:   return True\n",
    "        if len(nodeSet) == 2:\n",
    "            if nodeSet[0] not in node[nodeSet[1]]:  return True\n",
    "            for x in range(n):\n",
    "                if x not in nodeSet and x not in node[nodeSet[0]] and x not in node[nodeSet[1]]:    return True\n",
    "        if len(nodeSet) == 4:\n",
    "            nodePair = [[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 1, 2]]\n",
    "            for A, B, C, D in nodePair:\n",
    "                if nodeSet[A] not in node[nodeSet[B]] and nodeSet[C] not in node[nodeSet[D]]:   return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        node = [set() for _ in range(n)]\n",
    "        for x, y in edges:\n",
    "            node[x-1].add(y-1)\n",
    "            node[y-1].add(x-1)\n",
    "        \n",
    "        nodeSet = []\n",
    "        for i in range(n):\n",
    "            if len(node[i]) % 2 == 1:   nodeSet.append(i)\n",
    "        \n",
    "        if len(nodeSet) == 0:   return True\n",
    "        if len(nodeSet) == 2:\n",
    "            if nodeSet[0] not in node[nodeSet[1]]:  return True\n",
    "            for x in range(n):\n",
    "                if x not in nodeSet and x not in node[nodeSet[0]] and x not in node[nodeSet[1]]:    return True\n",
    "        if len(nodeSet) == 4:\n",
    "            nodePair = [[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 1, 2]]\n",
    "            for A, B, C, D in nodePair:\n",
    "                if nodeSet[A] not in node[nodeSet[B]] and nodeSet[C] not in node[nodeSet[D]]:   return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        node = [set() for _ in range(n)]\n",
    "        for x, y in edges:\n",
    "            node[x-1].add(y-1)\n",
    "            node[y-1].add(x-1)\n",
    "        \n",
    "        nodeSet = []\n",
    "        for i in range(n):\n",
    "            if len(node[i]) % 2 == 1:   nodeSet.append(i)\n",
    "        \n",
    "        if len(nodeSet) == 0:   return True\n",
    "        if len(nodeSet) == 2:\n",
    "            if nodeSet[0] not in node[nodeSet[1]]:  return True\n",
    "            for x in range(n):\n",
    "                if x not in nodeSet and x not in node[nodeSet[0]] and x not in node[nodeSet[1]]:    return True\n",
    "        if len(nodeSet) == 4:\n",
    "            nodePair = [[0, 1, 2, 3], [0, 2, 1, 3], [0, 3, 1, 2]]\n",
    "            for A, B, C, D in nodePair:\n",
    "                if nodeSet[A] not in node[nodeSet[B]] and nodeSet[C] not in node[nodeSet[D]]:   return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def isPossible(self, n: int, edges: List[List[int]]) -> bool:\n",
    "        book = [set() for i in range(n)]\n",
    "        degrees = [0 for i in range(n)]\n",
    "        for a,b in edges:\n",
    "            book[a-1].add(b-1)\n",
    "            book[b-1].add(a-1)\n",
    "            degrees[a-1]+=1\n",
    "            degrees[b-1]+=1\n",
    "        oddDegreeNodes = set()\n",
    "        for i in range(n):\n",
    "            if (degrees[i]&1)==1:\n",
    "                oddDegreeNodes.add(i)\n",
    "        if len(oddDegreeNodes)==0:\n",
    "            return True\n",
    "        if (len(oddDegreeNodes)&1)==1 or len(oddDegreeNodes)>4:\n",
    "            return False\n",
    "        if len(oddDegreeNodes)==2:\n",
    "            a,b = oddDegreeNodes\n",
    "            return a not in book[b] or any(\n",
    "                i != a and i != b and a not in book[i] and b not in book[i] for i in range(n)\n",
    "            )\n",
    "        a,b,c,d = oddDegreeNodes\n",
    "        if b not in book[a] and c not in book[d]:\n",
    "            return True\n",
    "        if c not in book[a] and b not in book[d]:\n",
    "            return True\n",
    "        if d not in book[a] and b not in book[c]:\n",
    "            return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        rungs = [0] + rungs\n",
    "        result = 0\n",
    "        for i in range(1, len(rungs)):\n",
    "            result += math.ceil((rungs[i]-rungs[i-1])/dist) - 1\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        rungs = [0] + rungs\n",
    "        for a, b in pairwise(rungs):\n",
    "            ans += (b - a + dist - 1) // dist - 1\n",
    "        return ans "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        count = 0\n",
    "        rungs = [0] + rungs\n",
    "        n = len(rungs)\n",
    "        for i in range(1, n):\n",
    "            diff = rungs[i]-rungs[i-1]\n",
    "            if diff > dist:\n",
    "                count += (diff-1)//dist\n",
    "        return count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        rungs = [0] + rungs\n",
    "        for x, y in pairwise(rungs):\n",
    "            if y - x > dist:\n",
    "                ans += (y - x - 1) // dist\n",
    "\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        last_h = 0\n",
    "        for r in rungs:\n",
    "            ans += int((r - 0.01 - last_h) // dist)\n",
    "            last_h = r\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        rungs.insert(0, 0)\n",
    "        for a, b in pairwise(rungs):\n",
    "            ans += (b-a-1) // dist\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        rungs = [0] + rungs\n",
    "        ans = 0\n",
    "        for x, y in pairwise(rungs):\n",
    "            ans += (y - x + dist - 1) // dist - 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        start = 0\n",
    "        res = 0\n",
    "        for i in range(len(rungs)):\n",
    "            if i == 0 :\n",
    "                tmp = rungs[0] \n",
    "                if dist < tmp:\n",
    "                    if tmp%dist!=0:\n",
    "                        res += int(floor(rungs[0]/dist))\n",
    "                    else:\n",
    "                        res += int(floor(rungs[0]/dist))-1\n",
    "                    \n",
    "            #i!=0\n",
    "            #i-1到不了i：\n",
    "            if i>0 and rungs[i]-rungs[i-1]>dist:\n",
    "                tmp = rungs[i]-rungs[i-1]\n",
    "                if tmp%dist!=0:\n",
    "                    res += int(floor((rungs[i]-rungs[i-1])/dist))\n",
    "                else:\n",
    "                    res += int(floor((rungs[i]-rungs[i-1])/dist))-1\n",
    "            #print(res)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        for i in range(len(rungs)-1):\n",
    "            ans += (rungs[i+1] - rungs[i] - 1) // dist\n",
    "        return ans + (rungs[0] - 1) // dist"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        curr=0\n",
    "        add=0\n",
    "        i=0\n",
    "        for h in rungs:\n",
    "            d=h-curr\n",
    "            add+=(h-curr-1)//dist\n",
    "            curr=h\n",
    "        return(add)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        c=0\n",
    "        rungs.insert(0,0)\n",
    "        n=len(rungs)\n",
    "        if n==1:\n",
    "            return 0\n",
    "        else:\n",
    "            for i in range(1,n):\n",
    "                if (rungs[i]-rungs[i-1])%dist==0:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist -1\n",
    "                else:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist\n",
    "        return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        if rungs[0] != 0:\n",
    "            rungs = [0] + rungs\n",
    "        for a, b in pairwise(rungs):\n",
    "            ans += (b-1-a) // dist\n",
    "        return ans\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        res = 0\n",
    "        cur = 0\n",
    "        for i in rungs:\n",
    "            if i - cur > dist:\n",
    "                res += math.ceil((i - cur) / dist) - 1\n",
    "            cur = i\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        rungs.insert(0, 0)\n",
    "        return sum((b-a-1) // dist for a, b in pairwise(rungs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        c=0\n",
    "        rungs.insert(0,0)\n",
    "        n=len(rungs)\n",
    "        if n==1:\n",
    "            return 0\n",
    "        else:\n",
    "            for i in range(1,n):\n",
    "                if (rungs[i]-rungs[i-1])%dist==0:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist -1\n",
    "                else:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist\n",
    "        return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        i,n,ans = 0,len(rungs),0\n",
    "        if rungs[0]%dist==0:\n",
    "            ans += rungs[0]//dist-1\n",
    "        else:\n",
    "            ans += rungs[0]//dist\n",
    "        while i<n-1:\n",
    "            if rungs[i]+dist<rungs[i+1]:\n",
    "                if (rungs[i+1]-rungs[i])%dist==0:\n",
    "                    ans += (rungs[i+1]-rungs[i])//dist-1\n",
    "                else:\n",
    "                    ans += (rungs[i+1]-rungs[i])//dist\n",
    "            i += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        c=0\n",
    "        rungs.insert(0,0)\n",
    "        n=len(rungs)\n",
    "        if n==1:\n",
    "            return 0\n",
    "        else:\n",
    "            for i in range(1,n):\n",
    "                if (rungs[i]-rungs[i-1])%dist==0:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist -1\n",
    "                else:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist\n",
    "        return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        i,n,ans = 0,len(rungs),0\n",
    "        if rungs[0]%dist==0:\n",
    "            ans += rungs[0]//dist-1\n",
    "        else:\n",
    "            ans += rungs[0]//dist\n",
    "        while i<n-1:\n",
    "            if rungs[i]+dist<rungs[i+1]:\n",
    "                if (rungs[i+1]-rungs[i])%dist==0:\n",
    "                    ans += (rungs[i+1]-rungs[i])//dist-1\n",
    "                else:\n",
    "                    ans += (rungs[i+1]-rungs[i])//dist\n",
    "            i += 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        if rungs[0] != 0:\n",
    "            rungs = [0] + rungs\n",
    "        for a, b in pairwise(rungs):\n",
    "            ans += (b-1-a) // dist\n",
    "        return ans\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        if rungs[0] != 0:\n",
    "            rungs = [0] + rungs\n",
    "        for a, b in pairwise(rungs):\n",
    "            ans += (b-1-a) // dist\n",
    "        return ans\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        c=0\n",
    "        rungs.insert(0,0)\n",
    "        n=len(rungs)\n",
    "        if n==1:\n",
    "            return 0\n",
    "        else:\n",
    "            for i in range(1,n):\n",
    "                if (rungs[i]-rungs[i-1])%dist==0:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist -1\n",
    "                else:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist\n",
    "        return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        c=0\n",
    "        rungs.insert(0,0)\n",
    "        n=len(rungs)\n",
    "        if n==1:\n",
    "            return 0\n",
    "        else:\n",
    "            for i in range(1,n):\n",
    "                if (rungs[i]-rungs[i-1])%dist==0:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist -1\n",
    "                else:\n",
    "                    c+=(rungs[i]-rungs[i-1])//dist\n",
    "        return c"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        result = 0\n",
    "        base = 0\n",
    "        for rung in rungs:\n",
    "            if rung - base <= dist: base = rung\n",
    "            else:\n",
    "                a = (rung - base)/dist\n",
    "                if a%1 == 0: result += (a-1)\n",
    "                else: result += math.floor(a)\n",
    "                base = rung\n",
    "        return int(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import sys\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: [int], dist: int) -> int:\n",
    "        #dp[i] 表示到达第i个节点处需要新增的最小数目\n",
    "        rungs.insert(0,0)\n",
    "        nn=len(rungs)\n",
    "        dp=[sys.maxsize for i in range(nn)]\n",
    "        dp[0]=0\n",
    "        for i in range(1,nn):\n",
    "            if rungs[i-1]+dist>=rungs[i]:\n",
    "                dp[i]=dp[i-1]\n",
    "                continue\n",
    "            tmp=(rungs[i]+dist-1-rungs[i-1])//dist\n",
    "            dp[i]=dp[i-1]+tmp-1\n",
    "\n",
    "        return dp[nn-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        cont = 0\n",
    "        stairs = [0]\n",
    "        for i in rungs:\n",
    "            stairs.append(i)\n",
    "        for j in range(len(stairs)-1):\n",
    "            dis = stairs[j+1] - stairs[j]\n",
    "            if dis > dist:\n",
    "                if dis%dist == 0:\n",
    "                    cont += (dis//dist)-1\n",
    "                else:\n",
    "                    cont += dis//dist\n",
    "        return cont"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        n=len(rungs)\n",
    "        count=0\n",
    "        ans=[]\n",
    "        ans.append(0)\n",
    "        for i in range(n):\n",
    "            ans.append(rungs[i])\n",
    "\n",
    "        for i in range(n):\n",
    "            tmp=ans[i+1]-ans[i]\n",
    "            if tmp>dist:\n",
    "                count=math.ceil(tmp/dist)-1 + count\n",
    "\n",
    "        return count\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "\n",
    "        i = 0\n",
    "        cur = 0\n",
    "        ans = 0\n",
    "\n",
    "        # 3 - 9,3\n",
    "        # 3 - 10, 3. 3,6,9,10\n",
    "        for i in range(len(rungs)):\n",
    "            if cur + dist >= rungs[i]:\n",
    "                cur = rungs[i]\n",
    "            else:\n",
    "                div, mod = divmod(rungs[i] - cur, dist)\n",
    "                ans += div - (mod == 0)\n",
    "                cur = rungs[i]\n",
    "\n",
    "        return ans\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans, pre = 0, 0\n",
    "        for h in rungs:\n",
    "            if (d := h - pre) > dist:\n",
    "                ans += (d - 1) // dist # 等价于 ceil(d / dist) - 1\n",
    "            pre = h\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        x = 0\n",
    "        fh = 0\n",
    "        for i in rungs:\n",
    "            if x+dist < i:\n",
    "                fh += (i-x)//dist - (0 if (i-x)%dist else 1)\n",
    "            x = i\n",
    "        return fh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs, dist: int) -> int:\n",
    "        pose = 0\n",
    "        count = 0\n",
    "        for step in rungs:\n",
    "            if step - pose > dist:\n",
    "                count+=(step - pose-1)//dist\n",
    "            pose = step\n",
    "        return count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        ans += (rungs[0] - 1) // dist \n",
    "        for i in range(len(rungs) - 1):\n",
    "            ans += (rungs[i+1] - rungs[i] - 1) // dist \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        res = 0   # 需要增设的梯子数目\n",
    "        curr = 0   # 当前高度\n",
    "        for h in rungs:\n",
    "            # 遍历数组计算高度差和最少添加数目，并更新当前高度\n",
    "            # d = h - curr\n",
    "            res += (h - curr - 1) // dist\n",
    "            curr = h\n",
    "        return res\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = (rungs[0] - 1) // dist\n",
    "        for i in range(1, len(rungs)):\n",
    "            if rungs[i] - rungs[i-1] > dist:\n",
    "                ans += (rungs[i] - rungs[i-1] - 1) // dist\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        cur = 0\n",
    "        for i in rungs:\n",
    "            ans += (i - cur) // dist - (((i - cur) % dist) == 0)\n",
    "            cur = i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        cur = ans = 0\n",
    "        for i in rungs:\n",
    "            ans += (i - cur - 1) // dist\n",
    "            cur = i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        t=(rungs[0]-1)//dist\n",
    "        for i in range(len(rungs)-1):\n",
    "            t+=(rungs[i+1]-rungs[i]-1)//dist\n",
    "        return t"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = (rungs[0] - 1) // dist\n",
    "        for i in range(1, len(rungs)):\n",
    "            ans += (rungs[i] - rungs[i-1] - 1) // dist\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        ans += (rungs[0] - 1) // dist \n",
    "        for i in range(len(rungs) - 1):\n",
    "            ans += (rungs[i+1] - rungs[i] - 1) // dist \n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        cur = 0\n",
    "        for i in rungs:\n",
    "            ans += (i - cur) // dist\n",
    "            if (i - cur) % dist == 0:\n",
    "                ans -= 1\n",
    "            cur = i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "            count = pre = 0\n",
    "            for item in rungs:\n",
    "                count += (item - pre - 1) // dist\n",
    "                pre = item\n",
    "            return count\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs, dist: int) -> int:\n",
    "        pose = 0\n",
    "        count = 0\n",
    "        for step in rungs:\n",
    "            if step - pose > dist:\n",
    "                count+=(step - pose-1)//dist\n",
    "            pose = step\n",
    "        return count"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        cur = 0\n",
    "        for i in rungs:\n",
    "            if i - cur > dist:\n",
    "                ans += (i - cur) // dist\n",
    "                if (i - cur) % dist == 0:\n",
    "                    ans -= 1\n",
    "            cur = i\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        a = 0\n",
    "        l = 0\n",
    "        for i in rungs:\n",
    "            dif = i - a\n",
    "            if dif <= dist:\n",
    "                a = i\n",
    "                continue\n",
    "            else:\n",
    "                if dif % dist == 0:\n",
    "                    taijie = dif // dist - 1\n",
    "                else:\n",
    "                    taijie = dif // dist\n",
    "                l += taijie\n",
    "            a = i\n",
    "        return l\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # * 模拟 + 贪心\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        res = 0   # 需要增设的梯子数目\n",
    "        curr = 0   # 当前高度\n",
    "        for h in rungs:\n",
    "            # 遍历数组计算高度差和最少添加数目，并更新当前高度\n",
    "            res += (h - curr - 1) // dist\n",
    "            curr = h\n",
    "\n",
    "        return res\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        res = 0   # 需要增设的梯子数目\n",
    "        curr = 0   # 当前高度\n",
    "        for h in rungs:\n",
    "            # 遍历数组计算高度差和最少添加数目，并更新当前高度\n",
    "        \n",
    "            res += (h - curr - 1) // dist\n",
    "            curr = h\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        cur = 0\n",
    "        for h in rungs:\n",
    "            ans += (h-cur-1)//dist\n",
    "            cur = h\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans=0\n",
    "        last_max=0\n",
    "        for it in rungs:\n",
    "            if(last_max+dist>=it):\n",
    "                last_max=it\n",
    "            else:\n",
    "                ans+=(it-last_max-1)//dist\n",
    "                last_max=it\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        x = 0\n",
    "        fh = 0\n",
    "        for i in rungs:\n",
    "            if x+dist < i:\n",
    "                fh += (i-x)//dist - (0 if (i-x)%dist else 1)\n",
    "            x = i\n",
    "        return fh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        return sum((b-a-1) // dist for a, b in pairwise(chain([0], rungs)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        start = ret = 0\n",
    "        for i in rungs:\n",
    "            if i - start > dist:\n",
    "                t = (i- start - 1) // dist\n",
    "                ret += t\n",
    "            start = i\n",
    "        return ret\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        # 公式咋推导的？\n",
    "        start = 0\n",
    "        res = 0\n",
    "        for h in rungs:\n",
    "            if h - start > dist:\n",
    "                t = (h-start-1)//dist\n",
    "                res += t\n",
    "            start = h\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        ht = 0\n",
    "        for h in rungs:\n",
    "            ans += (h - ht - 1) // dist\n",
    "            ht = h\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        return sum((b-a-1) // dist for a, b in pairwise([0] + rungs))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        # 公式咋推导的？\n",
    "        #(h - ht - 1) // dist ：减一的原因是，恰好是dist的k倍话，只要k-1个梯子，比如1和5之间只要一个dist=2的梯子（在3处），在前面-1能起到恰好k倍时最终结果-1的效果\n",
    "\n",
    "        start = 0\n",
    "        res = 0\n",
    "        for h in rungs:\n",
    "            if h - start > dist:\n",
    "                t = (h-start-1)//dist\n",
    "                res += t\n",
    "            start = h\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        l = 0\n",
    "        result = 0\n",
    "        for r in rungs:\n",
    "            if (r - l) % dist == 0:\n",
    "                result -= 1\n",
    "            result += (r - l) // dist\n",
    "            l = r\n",
    "        \n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        pre = 0\n",
    "        res = 0\n",
    "        for i in range(len(rungs)):\n",
    "            diff = rungs[i] - pre \n",
    "            if diff > dist:\n",
    "                res += diff//dist - 1\n",
    "                if diff%dist > 0:\n",
    "                    res += 1\n",
    "            pre = rungs[i]\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        now=0\n",
    "        ans=0\n",
    "        for i in range(len(rungs)):\n",
    "            if rungs[i]-now<=dist:\n",
    "                now = rungs[i]\n",
    "            else:\n",
    "                ans+=ceil((rungs[i]-now)/dist)-1\n",
    "                now = rungs[i]\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        new_rungs=[0]+rungs\n",
    "        t=0\n",
    "        dif_rungs=[new_rungs[i+1]-new_rungs[i] for i in range(len(new_rungs)-1)]\n",
    "        for i in dif_rungs:\n",
    "            if i>dist:\n",
    "                if i%dist==0:\n",
    "                    t+=i/dist-1\n",
    "                else:    \n",
    "                    t+=math.floor(i/dist)\n",
    "        return int(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        result = 0\n",
    "        pre = 0\n",
    "        for i in range(len(rungs)):\n",
    "            if(pre + dist >= rungs[i]):\n",
    "                pre = rungs[i]\n",
    "            else:\n",
    "                if((rungs[i]-pre) % dist == 0):\n",
    "                    result += (rungs[i]-pre) // dist - 1\n",
    "                else:\n",
    "                    result += (rungs[i]-pre) // dist\n",
    "                pre = rungs[i]\n",
    "        return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        ht = 0\n",
    "        for h in rungs:\n",
    "            ans += (h - ht - 1) // dist\n",
    "            ht = h\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        if len(rungs) == 0:\n",
    "            return 0\n",
    "        tmpNum, ans = 0, 0\n",
    "        for i in range(0, len(rungs)):\n",
    "            if rungs[i] - tmpNum <= dist:\n",
    "                tmpNum = rungs[i]\n",
    "                continue\n",
    "            tmp = 0\n",
    "            if (rungs[i] - tmpNum) % dist == 0:\n",
    "                tmp = 1\n",
    "            ans += (rungs[i] - tmpNum) // dist - tmp\n",
    "            tmpNum = rungs[i]\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        rungs = [0] + rungs\n",
    "        ans = 0\n",
    "        for x, y in pairwise(rungs):\n",
    "            if y - x > dist:\n",
    "               ans += (y - x + dist - 1) // dist - 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        new_rungs=[0]+rungs\n",
    "        t=0\n",
    "        for i in range(len(rungs)):\n",
    "            dif_value=new_rungs[i+1]-new_rungs[i]\n",
    "            if dif_value>dist:\n",
    "                if dif_value%dist==0:\n",
    "                    t+=dif_value/dist-1\n",
    "                else:    \n",
    "                    t+=math.floor(dif_value/dist)\n",
    "        return int(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        def f(x, y):\n",
    "            if (y-x) % dist:\n",
    "                return (y-x) // dist\n",
    "            else:\n",
    "                return (y-x) // dist - 1\n",
    "        ans = f(0, rungs[0])\n",
    "        for i in range(1, len(rungs)):\n",
    "            ans += f(rungs[i-1], rungs[i])\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        pre = 0\n",
    "        res = 0\n",
    "        for r in rungs:\n",
    "            diff = r - pre\n",
    "            if diff > dist:\n",
    "                add = diff//dist if diff%dist!=0 else (diff//dist-1)\n",
    "                res += add\n",
    "            pre = r\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        ans = 0\n",
    "        n = len(rungs) + 1\n",
    "        rungs = [0] + rungs\n",
    "        for i in range(n):\n",
    "            temp = rungs[i] - rungs[i - 1]\n",
    "            if temp > dist:\n",
    "                if temp % dist:\n",
    "                    ans += temp // dist\n",
    "                else:\n",
    "                    ans += temp // dist - 1\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import math\n",
    "\n",
    "class Solution:\n",
    "    def addRungs(self, rungs: List[int], dist: int) -> int:\n",
    "        res = cur = 0\n",
    "        for i in range(len(rungs)):\n",
    "            r = rungs[i]\n",
    "            if cur + dist >= r:\n",
    "                cur = r\n",
    "            else:\n",
    "                res = res + math.ceil((r - dist - cur)/dist)\n",
    "                cur = r\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "  def addOneRow(self, root, v, d):\n",
    "    \"\"\"\n",
    "    :type root: TreeNode\n",
    "    :type v: int\n",
    "    :type d: int\n",
    "    :rtype: TreeNode\n",
    "    \"\"\"\n",
    "    if d == 1:\n",
    "      newRoot = TreeNode( v )\n",
    "      newRoot.left = root\n",
    "      return newRoot\n",
    "\n",
    "    depth, curLevel, nextLevel = 1, list(), [ root ]\n",
    "    while depth < d - 1:\n",
    "      curLevel, nextLevel = nextLevel, curLevel\n",
    "      nextLevel.clear()\n",
    "      depth += 1\n",
    "\n",
    "      for node in curLevel:\n",
    "        if node.left != None:\n",
    "          nextLevel.append( node.left )\n",
    "        if node.right != None:\n",
    "          nextLevel.append( node.right )\n",
    "    curLevel = nextLevel\n",
    "\n",
    "    for node in curLevel:\n",
    "      newLeft = TreeNode( v )\n",
    "      newLeft.left = node.left\n",
    "      node.left = newLeft\n",
    "      newRight = TreeNode( v )\n",
    "      newRight.right = node.right\n",
    "      node.right = newRight\n",
    "\n",
    "    return root\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root, v, d):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :type v: int\n",
    "        :type d: int\n",
    "        :rtype: TreeNode\n",
    "        \"\"\"\n",
    "        if d == 1:\n",
    "            new_root = TreeNode(v)\n",
    "            new_root.left = root\n",
    "            # new_root.left = None\n",
    "            return new_root\n",
    "        cur = [root]\n",
    "        deep = 1\n",
    "        while deep!= d-1 :\n",
    "            next_level = []\n",
    "            for node in cur:\n",
    "                if node.left:\n",
    "                    next_level.append(node.left)\n",
    "                if node.right:\n",
    "                    next_level.append(node.right)\n",
    "            deep += 1\n",
    "            cur = next_level\n",
    "        for node in cur:\n",
    "            tmp1 = node.left\n",
    "            node.left = TreeNode(v)\n",
    "            node.left.left = tmp1\n",
    "            tmp2 = node.right\n",
    "            node.right = TreeNode(v)\n",
    "            node.right.right = tmp2\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root, v, d):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :type v: int\n",
    "        :type d: int\n",
    "        :rtype: TreeNode\n",
    "        \"\"\"\n",
    "        dummy = TreeNode(0)\n",
    "        dummy.left, que = root, collections.deque([dummy])\n",
    "        for i in range(d - 1):\n",
    "            l = len(que)\n",
    "            for i in range(l):\n",
    "                cur = que.popleft()\n",
    "                if cur.left:\n",
    "                    que.append(cur.left)\n",
    "                if cur.right:\n",
    "                    que.append(cur.right)\n",
    "        for i in que:\n",
    "            l, r = TreeNode(v), TreeNode(v)\n",
    "            i.left, l.left, i.right, r.right = l, i.left, r, i.right\n",
    "        return dummy.left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root, v, d):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :type v: int\n",
    "        :type d: int\n",
    "        :rtype: TreeNode\n",
    "        \"\"\"\n",
    "        nodes = []\n",
    "        for i in range(d-1):\n",
    "            if not nodes:\n",
    "                nodes.append(root)\n",
    "            else:\n",
    "                temp = []\n",
    "                for node in nodes:\n",
    "                    if node.left:\n",
    "                        temp.append(node.left)\n",
    "                    if node.right:\n",
    "                        temp.append(node.right)\n",
    "                nodes = temp\n",
    "        if not nodes:\n",
    "            node = TreeNode(v)\n",
    "            node.left = root\n",
    "            return node\n",
    "        for node in nodes:\n",
    "            templ = TreeNode(v)\n",
    "            tempr = TreeNode(v)\n",
    "            templ.left = node.left\n",
    "            tempr.right = node.right\n",
    "            node.left = templ\n",
    "            node.right = tempr\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root, v, d):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :type v: int\n",
    "        :type d: int\n",
    "        :rtype: TreeNode\n",
    "        \"\"\"\n",
    "        if not root:\n",
    "            return root\n",
    "        if d == 1:\n",
    "            l = TreeNode(v)\n",
    "            l.left = root\n",
    "            root = l\n",
    "        elif d == 2:\n",
    "            l = TreeNode(v)\n",
    "            r = TreeNode(v)\n",
    "            l.left = root.left\n",
    "            r.right = root.right\n",
    "            root.left = l\n",
    "            root.right = r\n",
    "        else:\n",
    "            root.left = self.addOneRow(root.left,v,d-1)\n",
    "            root.right = self.addOneRow(root.right,v,d-1)\n",
    "        return root\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def addOneRow(self, root, v, d):\n",
    "        def dfs(r, dep):\n",
    "            if not r:\n",
    "                return\n",
    "            if dep == d - 1:\n",
    "                t = TreeNode(v)\n",
    "                r.left, t.left = t, r.left\n",
    "                t = TreeNode(v)\n",
    "                r.right, t.right = t, r.right\n",
    "                return\n",
    "            else:\n",
    "                dfs(r.left, dep + 1)\n",
    "                dfs(r.right, dep + 1)\n",
    "                \n",
    "        if d == 1:\n",
    "            t = TreeNode(v)\n",
    "            t.left = root\n",
    "            return t\n",
    "        dfs(root, 1)\n",
    "        return root\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root, v, d):\n",
    "        \"\"\"\n",
    "        :type root: TreeNode\n",
    "        :type v: int\n",
    "        :type d: int\n",
    "        :rtype: TreeNode\n",
    "        \"\"\"\n",
    "        if d == 1:\n",
    "            r = TreeNode(v)\n",
    "            r.left = root\n",
    "            return r\n",
    "        def dfs(node, d, v, cd):\n",
    "            if not node:\n",
    "                return\n",
    "            if cd == d - 1:\n",
    "                l, r = node.left, node.right\n",
    "                node.left = TreeNode(v)\n",
    "                node.right = TreeNode(v)\n",
    "                node.left.left = l\n",
    "                node.right.right = r\n",
    "            elif cd < d - 1:\n",
    "                dfs(node.left, d, v, cd + 1)\n",
    "                dfs(node.right, d, v, cd + 1)\n",
    "        dfs(root, d, v, 1)\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d == 1:\n",
    "            n = TreeNode(v)\n",
    "            n.left = root\n",
    "            return n\n",
    "        node_list = []\n",
    "        if root:\n",
    "            node_list.append(root)\n",
    "        for i in range(1, d-1):\n",
    "            new_list = []\n",
    "            for node in node_list:\n",
    "                if node.left:\n",
    "                    new_list.append(node.left)\n",
    "                if node.right:\n",
    "                    new_list.append(node.right)\n",
    "            node_list = new_list\n",
    "        if node_list:\n",
    "            for node in node_list:\n",
    "                l = TreeNode(v)\n",
    "                l.left = node.left\n",
    "                r = TreeNode(v)\n",
    "                r.right = node.right\n",
    "                node.left = l\n",
    "                node.right = r\n",
    "            return root\n",
    "        else:\n",
    "            return None\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d==1:\n",
    "            head = TreeNode(v)\n",
    "            head.left = root\n",
    "            return head\n",
    "        \n",
    "        queue = [root]\n",
    "\n",
    "        while queue and d>2:\n",
    "            for i in range(len(queue)):\n",
    "                node = queue.pop(0)\n",
    "                if node.left:\n",
    "                    queue.append(node.left)\n",
    "                if node.right:\n",
    "                    queue.append(node.right)\n",
    "\n",
    "            d -= 1\n",
    "\n",
    "        while queue:\n",
    "            node = queue.pop(0)\n",
    "\n",
    "            temp = TreeNode(v)\n",
    "            if node.left:\n",
    "                temp.left = node.left\n",
    "            node.left = temp\n",
    "\n",
    "            temp = TreeNode(v)\n",
    "            if node.right:\n",
    "                temp.right = node.right\n",
    "            node.right = temp\n",
    "            \n",
    "        return root\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d == 1:\n",
    "            t, t.left = TreeNode(v), root\n",
    "            return t\n",
    "\n",
    "        queue = [root]\n",
    "        level, flag =0, True\n",
    "        while queue and flag:\n",
    "            temp = []\n",
    "            level += 1\n",
    "            for node in queue:\n",
    "                if level == d-1:\n",
    "                    t = TreeNode(v)\n",
    "                    t.left, node.left = node.left, t\n",
    "                    t = TreeNode(v)\n",
    "                    t.right, node.right = node.right, t\n",
    "                    flag = False\n",
    "                else:\n",
    "                    if node.left:\n",
    "                        temp.append(node.left)\n",
    "                    if node.right:\n",
    "                        temp.append(node.right)\n",
    "            queue = temp \n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "from collections import deque\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d == 1:\n",
    "            newroot = TreeNode(v)\n",
    "            newroot.left = root\n",
    "            return newroot\n",
    "        queue = deque([root])\n",
    "        level = 1\n",
    "        while queue:\n",
    "            length = len(queue)\n",
    "            if level == d - 1:\n",
    "                for i in range(length):\n",
    "                    curr = queue.popleft()\n",
    "                    nodel = TreeNode(v)\n",
    "                    nodel.left = curr.left\n",
    "                    curr.left = nodel\n",
    "                    noder = TreeNode(v)\n",
    "                    noder.right = curr.right\n",
    "                    curr.right = noder\n",
    "                return root\n",
    "            else:\n",
    "                for i in range(length):\n",
    "                    curr = queue.popleft()\n",
    "                    if curr.left:\n",
    "                        queue.append(curr.left)\n",
    "                    if curr.right:\n",
    "                        queue.append(curr.right)\n",
    "            level += 1\n",
    "        return root\n",
    "\n",
    "\n",
    "                \n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d ==1:\n",
    "            new_root = TreeNode(v)\n",
    "            new_root.left = root\n",
    "            return new_root\n",
    "        stack = [root]\n",
    "        while d > 2 :\n",
    "            for i in range(len(stack)):\n",
    "                node = stack.pop(0)\n",
    "                if node.left:\n",
    "                    stack.append(node.left)\n",
    "                if node.right:\n",
    "                    stack.append(node.right)\n",
    "            d -= 1\n",
    "        for i in range(len(stack)):\n",
    "            node = stack.pop(0)\n",
    "            new_left = TreeNode(v)\n",
    "            temp_left = node.left\n",
    "            node.left = new_left\n",
    "            new_left.left = temp_left\n",
    "            new_right = TreeNode(v)\n",
    "            temp_right = node.right\n",
    "            node.right = new_right\n",
    "            new_right.right = temp_right\n",
    "        return root\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d == 1:\n",
    "            node_n = TreeNode(v)\n",
    "            node_n.left = root\n",
    "            return node_n\n",
    "        stack = [root]\n",
    "        if d == 2:\n",
    "            if root:\n",
    "#                if root.left:\n",
    "                tmp = root.left\n",
    "                newtmp = TreeNode(v)\n",
    "                root.left = newtmp\n",
    "                newtmp.left = tmp\n",
    "#                if root.right:\n",
    "                tmp = root.right\n",
    "                newtmp = TreeNode(v)\n",
    "                root.right = newtmp\n",
    "                newtmp.right = tmp\n",
    "            return root               \n",
    "        while d > 2:\n",
    "            if not stack:\n",
    "                return root\n",
    "            list_v = []\n",
    "            while len(stack) > 0:\n",
    "                tmp = stack.pop()\n",
    "                if tmp.left:\n",
    "                    list_v.append(tmp.left)\n",
    "                if tmp.right:\n",
    "                    list_v.append(tmp.right)\n",
    "            stack = list_v\n",
    "            d -= 1\n",
    "        print(stack)\n",
    "        if d == 2:\n",
    "            for node in stack:\n",
    "#                if node.left:\n",
    "                tmp = node.left\n",
    "                newtmp = TreeNode(v)\n",
    "                node.left = newtmp\n",
    "                newtmp.left = tmp\n",
    "#                if node.right:\n",
    "                tmp = node.right\n",
    "                newtmp = TreeNode(v)\n",
    "                node.right = newtmp\n",
    "                newtmp.right = tmp\n",
    "        return root                    \n",
    "\n",
    "        \n",
    "        \n",
    "        \n",
    "                \n",
    "            \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        import queue\n",
    "        if d == 1:\n",
    "            tn = TreeNode(v)\n",
    "            tn.left = root\n",
    "            return tn\n",
    "        q = queue.Queue()\n",
    "        q.put((root, 1))\n",
    "        while q.qsize() > 0:\n",
    "            tn, deep = q.get()\n",
    "            if deep == d - 1:\n",
    "                ltn = TreeNode(v)\n",
    "                ltn.left = tn.left\n",
    "                tn.left = ltn\n",
    "                rtn = TreeNode(v)\n",
    "                rtn.right = tn.right\n",
    "                tn.right = rtn\n",
    "            else:\n",
    "                if tn.left != None:\n",
    "                    q.put((tn.left, deep+1))\n",
    "                if tn.right != None:\n",
    "                    q.put((tn.right, deep+1))\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d == 1:\n",
    "            out = TreeNode(v)\n",
    "            out.left = root\n",
    "            return out\n",
    "        i = 2\n",
    "        queue = [root]\n",
    "        while i < d:\n",
    "            next_queue = []\n",
    "            for node in queue:\n",
    "                if node.left:\n",
    "                    next_queue.append(node.left)\n",
    "                if node.right:\n",
    "                    next_queue.append(node.right)\n",
    "            queue = next_queue\n",
    "            i += 1\n",
    "        for node in queue:\n",
    "            tmp_1 = node.left\n",
    "            tmp_2 = node.right\n",
    "            node.left = TreeNode(v)\n",
    "            node.left.left = tmp_1\n",
    "            node.right = TreeNode(v)\n",
    "            node.right.right = tmp_2\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if d == 1:\n",
    "            p = TreeNode(v)\n",
    "            p.left = root\n",
    "            return p\n",
    "        queue = [root]\n",
    "        deep = 2\n",
    "        while deep < d:\n",
    "            length = len(queue)\n",
    "            for _ in range(length):\n",
    "                p = queue.pop(0)\n",
    "                if p.left:\n",
    "                    queue.append(p.left)\n",
    "                if p.right:\n",
    "                    queue.append(p.right)\n",
    "            deep += 1\n",
    "        for node in queue:\n",
    "            Left = TreeNode(v)\n",
    "            Right = TreeNode(v)\n",
    "            Left.left = node.left\n",
    "            Right.right = node.right\n",
    "            node.left = Left\n",
    "            node.right= Right\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        # 如果d是1，则直接创立一个node，并把root赋予给node.left并返回node\n",
    "        if d == 1:\n",
    "            node = TreeNode(v)\n",
    "            node.left = root\n",
    "            return node\n",
    "        # 当前深度为1\n",
    "        current = 1\n",
    "        queue = [root]\n",
    "        # 否则开始正常的bfs\n",
    "        while len(queue) > 0:\n",
    "            size = len(queue)\n",
    "            for i in range(size):\n",
    "                node = queue.pop(0)\n",
    "                left = node.left\n",
    "                right = node.right\n",
    "                # 因为要在深度的上一层进行修改，所以是d-1\n",
    "                if current == d-1:\n",
    "                    node.left = TreeNode(v)\n",
    "                    node.right = TreeNode(v)\n",
    "                    node.left.left = left\n",
    "                    node.right.right = right\n",
    "                    # 添加完所有该层节点，可以直接return root了，这里用break一样\n",
    "                    if i == size-1:\n",
    "                        break\n",
    "                # 否则开始正常的bfs\n",
    "                if node.left is not None:\n",
    "                    queue.append(node.left)\n",
    "                if node.right is not None:\n",
    "                    queue.append(node.right)\n",
    "            current += 1\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, val: int, depth: int) -> TreeNode:\n",
    "        if depth==1:\n",
    "            cur=TreeNode(val)\n",
    "            cur.left=root\n",
    "            return cur\n",
    "        queue=[root]\n",
    "        for i in range(depth-2):\n",
    "            tmp=[]\n",
    "            for node in queue:\n",
    "                if node.left:\n",
    "                    tmp.append(node.left)\n",
    "                if node.right:\n",
    "                    tmp.append(node.right)\n",
    "            queue=tmp\n",
    "        for node in queue:\n",
    "            left=TreeNode(val)\n",
    "            right=TreeNode(val)\n",
    "            left.left=node.left\n",
    "            right.right=node.right\n",
    "            node.left=left\n",
    "            node.right=right\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if depth == 1:\n",
    "            t = TreeNode()\n",
    "            t.val = val\n",
    "            t.left = root\n",
    "            return t \n",
    "        d = 0\n",
    "        q = deque([root])\n",
    "        while q:\n",
    "            d += 1\n",
    "            for _ in range(len(q)):\n",
    "                node = q.popleft()\n",
    "                if d == depth-1:\n",
    "                    left, right = TreeNode(val=val),TreeNode(val=val)\n",
    "                    left.left = node.left\n",
    "                    right.right = node.right\n",
    "                    node.left = left\n",
    "                    node.right = right\n",
    "                else:\n",
    "                    if node.left:\n",
    "                        q.append(node.left)\n",
    "                    if node.right:\n",
    "                        q.append(node.right)\n",
    "        return root\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if depth==1:\n",
    "            node = TreeNode(val)\n",
    "            node.left = root\n",
    "            return node\n",
    "        dict_node = {}\n",
    "        curr_dep = 1\n",
    "        layer_node=[root]\n",
    "        while layer_node!=[]:\n",
    "            layer_width = len(layer_node)\n",
    "            #print(layer_width)\n",
    "            tmp = []\n",
    "            if curr_dep==depth-1:\n",
    "                #print('curr_dep',curr_dep)\n",
    "                #print(layer_node)\n",
    "                #print(root)\n",
    "                for node in layer_node:\n",
    "                    insert1 = TreeNode(val)\n",
    "                    insert1.left = node.left\n",
    "                    insert2 = TreeNode(val)\n",
    "                    insert2.right = node.right\n",
    "                    node.left = insert1\n",
    "                    node.right = insert2\n",
    "                    \n",
    "                return root\n",
    "            else:\n",
    "                for i in range(layer_width):\n",
    "                    node = layer_node.pop(0)\n",
    "                    if node.left:\n",
    "                        layer_node.append(node.left)\n",
    "                    if node.right:\n",
    "                        layer_node.append(node.right)\n",
    "            #print(root)\n",
    "            curr_dep = curr_dep+1\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if depth == 1:\n",
    "            return TreeNode(val,root,None)\n",
    "        q = [[root,1]]\n",
    "        while q:\n",
    "            tmp = []\n",
    "            for node,i in q:\n",
    "                if i == depth:       # i==depth-1循环完了，说明所有i=depth-1的node增加完了\n",
    "                    return root\n",
    "                if i == depth-1:     # 如果在这里return root，就只有第一个node加了，后面都没加。\n",
    "                    node.left = TreeNode(val,node.left,None)\n",
    "                    node.right = TreeNode(val,None,node.right)\n",
    "\n",
    "                if node.left:\n",
    "                    tmp.append([node.left,i+1])\n",
    "                if node.right:\n",
    "                    tmp.append([node.right,i+1])\n",
    "\n",
    "            q= tmp"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if depth == 1:\n",
    "            return TreeNode(val, left=root)\n",
    "        q = []\n",
    "        q.append(root)\n",
    "        dep = 1\n",
    "        while q:\n",
    "            l = len(q)\n",
    "            cur = []\n",
    "            for i in range(l):\n",
    "                n = q.pop(0)\n",
    "                cur.append(n)\n",
    "                if n.left:\n",
    "                    q.append(n.left)\n",
    "                if n.right:\n",
    "                    q.append(n.right)\n",
    "            if dep == depth - 1:\n",
    "                for node in cur:\n",
    "                    left = node.left\n",
    "                    right = node.right\n",
    "                    node.left = TreeNode(val, left=left)\n",
    "                    node.right = TreeNode(val, right=right)\n",
    "                return root\n",
    "            dep += 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "from typing import Optional\n",
    "from collections import deque\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        \"\"\"\n",
    "\n",
    "        :param root:\n",
    "        :param val:\n",
    "        :param depth:\n",
    "        :return:\n",
    "        \"\"\"\n",
    "        if depth == 1:\n",
    "            newNode = TreeNode(val)\n",
    "            newNode.left = root\n",
    "            return newNode\n",
    "        dq = deque()\n",
    "        dq.append((root, 1))\n",
    "        toappend = []\n",
    "        m1 = {}\n",
    "        while len(dq) > 0:\n",
    "            first, dp = dq.popleft()\n",
    "            if dp not in m1:\n",
    "                m1[dp] = [first]\n",
    "            else:\n",
    "                m1[dp].append(first)\n",
    "            if first.left:\n",
    "                dq.append((first.left, dp + 1))\n",
    "            if first.right:\n",
    "                dq.append((first.right, dp + 1))\n",
    "            if dp == depth - 1:\n",
    "                toappend.append(first)\n",
    "            if dp > depth:\n",
    "                break\n",
    "        if len(toappend) > 0:\n",
    "            for i in toappend:\n",
    "                if i.left:\n",
    "                    tmp = i.left\n",
    "                    newnode = TreeNode(val)\n",
    "                    i.left = newnode\n",
    "                    newnode.left = tmp\n",
    "                else:\n",
    "                    v1 = TreeNode(val)\n",
    "                    i.left = v1\n",
    "                if i.right:\n",
    "                    tmp = i.right\n",
    "                    newnode = TreeNode(val)\n",
    "                    i.right = newnode\n",
    "                    newnode.right = tmp\n",
    "                else:\n",
    "                    v1 = TreeNode(val)\n",
    "                    i.right = v1\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.left = None\n",
    "#         self.right = None\n",
    "\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, v: int, d: int) -> TreeNode:\n",
    "        if not root:\n",
    "            return\n",
    "\n",
    "        if d == 1:\n",
    "            node = TreeNode(v)\n",
    "            node.left = root\n",
    "            return node\n",
    "\n",
    "        if d == 2:\n",
    "            L = TreeNode(v)  # 新左节点\n",
    "            R = TreeNode(v)  # 新右节点\n",
    "\n",
    "            L.left = root.left\n",
    "            R.right = root.right\n",
    "\n",
    "            root.left = L\n",
    "            root.right = R\n",
    "            return root\n",
    "\n",
    "        self.addOneRow(root.left, v, d-1)\n",
    "        self.addOneRow(root.right, v, d-1)\n",
    "        return root\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if depth == 1:\n",
    "            return TreeNode(val, root, None)\n",
    "        level = [root]\n",
    "        for i in range(2, depth):\n",
    "            temp = []\n",
    "            for node in level:\n",
    "                if node.left:\n",
    "                    temp.append(node.left)\n",
    "                if node.right:\n",
    "                    temp.append(node.right)\n",
    "            level = temp\n",
    "        for node in level:\n",
    "            node.left = TreeNode(val, node.left, None)\n",
    "            node.right = TreeNode(val, None, node.right)\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if root:\n",
    "            nodes = [root]\n",
    "        else:\n",
    "            return None\n",
    "        if depth == 1:\n",
    "            root_ = TreeNode(val)\n",
    "            root_.left = root\n",
    "            return root_\n",
    "        else:\n",
    "            current_depth = 1\n",
    "            while current_depth < depth - 1:\n",
    "                lens = len(nodes)\n",
    "                # print(lens)\n",
    "                for i in range(lens):\n",
    "                    item = nodes.pop(0)\n",
    "                    if item.left:\n",
    "                        nodes.append(item.left)\n",
    "                    if item.right:\n",
    "                        nodes.append(item.right)\n",
    "                current_depth += 1\n",
    "            # print(nodes)\n",
    "            for node in nodes:\n",
    "                if node.left:\n",
    "                    tmp = node.left\n",
    "                    node.left = TreeNode(val)\n",
    "                    node.left.left = tmp\n",
    "                else:\n",
    "                    node.left = TreeNode(val)\n",
    "\n",
    "                if node.right:\n",
    "                    tmp = node.right\n",
    "                    node.right = TreeNode(val)\n",
    "                    node.right.right = tmp\n",
    "                else:\n",
    "                    node.right = TreeNode(val)\n",
    "            return root\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if depth == 1:\n",
    "            return TreeNode(val, root)\n",
    "        \n",
    "        queue = [root]\n",
    "        d = 1\n",
    "\n",
    "        while queue:\n",
    "            if d == depth - 1:\n",
    "                for _ in range(len(queue)):\n",
    "                    node = queue.pop(0)\n",
    "                    left_old, right_old = node.left, node.right\n",
    "                    node.left = TreeNode(val, left_old)\n",
    "                    node.right = TreeNode(val, None, right_old)\n",
    "                return root\n",
    "            else:\n",
    "                for _ in range(len(queue)):\n",
    "                    node = queue.pop(0)\n",
    "                    if node.left:\n",
    "                        queue.append(node.left)\n",
    "                    if node.right:\n",
    "                        queue.append(node.right)\n",
    "            d += 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "\n",
    "        if depth == 1:\n",
    "            newNode = TreeNode(val)\n",
    "            newNode.left = root\n",
    "            return newNode\n",
    "\n",
    "        def dfs(node, h):\n",
    "\n",
    "            if not node:\n",
    "                return\n",
    "            \n",
    "            if h == depth -1:\n",
    "                \n",
    "                newNode = TreeNode(val)\n",
    "                newNode.left = node.left\n",
    "                node.left = newNode\n",
    "                \n",
    "                newNode = TreeNode(val)\n",
    "                newNode.right = node.right\n",
    "                node.right = newNode\n",
    "                \n",
    "                return node\n",
    "\n",
    "            node.left = dfs(node.left, h+1)\n",
    "            node.right = dfs(node.right, h + 1)\n",
    "            return node\n",
    "        \n",
    "        dfs(root, 1)\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if depth == 1:\n",
    "            tmp = TreeNode(val,left=root)\n",
    "            return tmp\n",
    "        def bfs(root,lvl):\n",
    "            if lvl == depth - 1:\n",
    "                tmpl = TreeNode(val, left=root.left)\n",
    "                tmpr = TreeNode(val, right=root.right)\n",
    "                root.left = tmpl\n",
    "                root.right = tmpr\n",
    "            if root.left:\n",
    "                bfs(root.left,lvl+1)\n",
    "            if root.right:\n",
    "                bfs(root.right,lvl+1)\n",
    "        bfs(root,1)\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        def AddOneRow(n,root):\n",
    "            root_left = TreeNode(val)\n",
    "            root_right = TreeNode(val)\n",
    "            if depth == 1:\n",
    "                root_left.left = root\n",
    "                root = root_left\n",
    "            elif n == depth-1 and root:\n",
    "                root_left.left = root.left\n",
    "                root.left = root_left\n",
    "            # if n == depth-1 and root.right:\n",
    "                root_right.right = root.right\n",
    "                root.right = root_right\n",
    "            elif root:\n",
    "                left = AddOneRow(n+1,root.left)\n",
    "                right = AddOneRow(n+1,root.right)\n",
    "            return root\n",
    "        return AddOneRow(1,root)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: TreeNode, val: int, depth: int) -> TreeNode:\n",
    "        if root == None:\n",
    "            return\n",
    "        if depth == 1:\n",
    "            return TreeNode(val, root, None)\n",
    "        if depth == 2:\n",
    "            root.left = TreeNode(val, root.left, None)\n",
    "            root.right = TreeNode(val, None, root.right)\n",
    "        else:\n",
    "            root.left = self.addOneRow(root.left, val, depth - 1)\n",
    "            root.right = self.addOneRow(root.right, val, depth - 1)\n",
    "        return root\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for a binary tree node.\n",
    "# class TreeNode:\n",
    "#     def __init__(self, val=0, left=None, right=None):\n",
    "#         self.val = val\n",
    "#         self.left = left\n",
    "#         self.right = right\n",
    "class Solution:\n",
    "    def addOneRow(self, root: Optional[TreeNode], val: int, depth: int) -> Optional[TreeNode]:\n",
    "        if root == None:\n",
    "            return\n",
    "        if depth == 1:\n",
    "            return TreeNode(val, root, None)\n",
    "        if depth == 2:\n",
    "            root.left = TreeNode(val, root.left, None)\n",
    "            root.right = TreeNode(val, None, root.right)\n",
    "        else:\n",
    "            root.left = self.addOneRow(root.left, val, depth - 1)\n",
    "            root.right = self.addOneRow(root.right, val, depth - 1)\n",
    "        return root"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        sys.set_int_max_str_digits(10**4)\n",
    "        return str(int(num1) + int(num2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        a=0\n",
    "        ans=''\n",
    "        n=max(len(num1),len(num2))\n",
    "        num1='0'*(n-len(num1))+num1\n",
    "        num2='0'*(n-len(num2))+num2\n",
    "        i=-1\n",
    "        while True:\n",
    "            k=int(num1[i])+int(num2[i])+a\n",
    "            ans=ans+str(k%10)\n",
    "            if k>=10:\n",
    "                a=1\n",
    "            else:\n",
    "                a=0\n",
    "            if i==-n:\n",
    "                break\n",
    "            i-=1\n",
    "        if a:\n",
    "            ans=ans+str(a)\n",
    "        return ans[::-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "import sys\n",
    "\n",
    "# 增加整数转换为字符串的限制\n",
    "sys.set_int_max_str_digits(10000) \n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        temp1 = temp2 = 0\n",
    "        for i in range(1,len(num1)+1):\n",
    "            temp1 += int(num1[-i]) * (10**(i - 1))\n",
    "        for i in range(1,len(num2)+1):\n",
    "            temp2 += int(num2[-i]) * (10**(i - 1))\n",
    "        return str(temp1+temp2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n ,m = len(num1) , len(num2)\n",
    "        i ,j = n - 1,m - 1\n",
    "        f = 0\n",
    "        res = \"\"\n",
    "        while i>=0 or j >=0 :\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "\n",
    "            y = n2 + n1 + f\n",
    "            f = y // 10\n",
    "            res = str(y % 10) + res\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "\n",
    "        return \"1\" + res if f == 1 else res "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n1,n2=len(num1),len(num2)\n",
    "        if n1<n2:num1=(n2-n1)*\"0\"+num1\n",
    "        if n2<n1:num2=(n1-n2)*\"0\"+num2\n",
    "\n",
    "        num,cin=\"\",0\n",
    "        for i in range(max(n1,n2)-1,-1,-1):\n",
    "            t=int(num1[i])+int(num2[i])+cin\n",
    "            cin,m=t//10,t%10\n",
    "            num=str(m)+num\n",
    "        return num if cin==0 else \"1\"+num\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        answer = ''\n",
    "        num1 = num1[::-1]\n",
    "        num2 = num2[::-1]\n",
    "        r = 0\n",
    "        c = 0\n",
    "        while len(num1) != len(num2):\n",
    "            if len(num1)<len(num2):\n",
    "                num1 += '0'\n",
    "            else:\n",
    "                num2 += '0'\n",
    "        while r<len(num1):\n",
    "            a = int(num1[r])\n",
    "            b = int(num2[r])\n",
    "            if a+b+c <10:\n",
    "                answer += str(a+b+c)\n",
    "                c = 0\n",
    "            else:\n",
    "                answer += str(a+b+c-10)\n",
    "                c = 1\n",
    "            r += 1\n",
    "        if c == 1:\n",
    "            answer += '1'\n",
    "        return answer[::-1]\n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        m, n = len(num1), len(num2)\n",
    "        i, j = m-1, n-1\n",
    "        carry = 0\n",
    "        ans = ''\n",
    "\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            s = n1 + n2 + carry\n",
    "            carry = s // 10\n",
    "            ans = str(s % 10) + ans\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        \n",
    "        return '1' + ans if carry else ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n1 = len(num1)\n",
    "        n2 = len(num2)\n",
    "        p1 = n1-1\n",
    "        p2 = n2-1\n",
    "        res = ''\n",
    "        temp = 0\n",
    "        while p1 >= 0 or p2 >= 0:\n",
    "            # 两树的和\n",
    "            s1 = '0' if p1 < 0 else num1[p1]\n",
    "            s2 = '0' if p2 < 0 else num2[p2]\n",
    "            two_sum = int(s1)+int(s2)+temp\n",
    "            # 计算进位\n",
    "            temp = two_sum // 10\n",
    "            # 计算余数\n",
    "            left = two_sum % 10\n",
    "            res = str(left)+res\n",
    "            p1 -= 1\n",
    "            p2 -= 1\n",
    "        return '1'+res if temp == 1 else res\n",
    "\n",
    "         \n",
    "\n",
    "             "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        t = 0\n",
    "        res = ''\n",
    "        l1, l2 = len(num1), len(num2)\n",
    "        x, y = l1 -1 , l2 - 1\n",
    "        while x >= 0 and y >= 0:\n",
    "            T = int(num1[x]) + int(num2[y]) + t\n",
    "            t = 1 if T >= 10 else 0\n",
    "            res = str(T % 10) + res\n",
    "            x -= 1\n",
    "            y -= 1\n",
    "        while x >= 0:\n",
    "            T = int(num1[x]) + t\n",
    "            t = 1 if T >= 10 else 0\n",
    "            res = str(T % 10) + res \n",
    "            x -= 1\n",
    "        while y >= 0:\n",
    "            T = int(num2[y]) + t\n",
    "            t = 1 if T >= 10 else 0\n",
    "            res = str(T % 10) + res \n",
    "            y -= 1\n",
    "        if t:\n",
    "            return str(t) + res\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n1,n2 = len(num1),len(num2)\n",
    "        k1,k2,t = n1-1,n2-1,0\n",
    "        ans = ''\n",
    "        while k1>=0 or k2>=0:\n",
    "            t +=  int(num1[k1]) if k1>=0 else 0\n",
    "            t += int(num2[k2]) if k2>=0 else 0\n",
    "\n",
    "            ans = str( t % 10) + ans\n",
    "            t = t//10\n",
    "            \n",
    "            k1 -= 1\n",
    "            k2 -= 1\n",
    "\n",
    "        if t:\n",
    "            ans = str(t) + ans\n",
    "        return ans\n",
    "\n",
    "         \n",
    "\n",
    "             "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return \"1\" + res if carry else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "\n",
    "        res = \"\"\n",
    "\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "\n",
    "        while i >= 0 or j >= 0:\n",
    "\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "\n",
    "            tmp = n1 + n2 + carry\n",
    "\n",
    "            carry = tmp // 10\n",
    "\n",
    "            res = str(tmp % 10) + res\n",
    "\n",
    "            i, j = i - 1, j - 1\n",
    "\n",
    "        return \"1\" + res if carry else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i = len(num1) - 1\n",
    "        j = len(num2) - 1\n",
    "        flag = 0   # 进位标志\n",
    "        ans = \"\"\n",
    "        while (i >= 0 or j >= 0 or flag != 0):\n",
    "            x = int(num1[i]) if i >= 0 else 0\n",
    "            y = int(num2[j]) if j >= 0 else 0\n",
    "            ret = x + y + flag\n",
    "            ans += str(ret % 10)\n",
    "            flag = ret // 10\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return ans[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        ans = \"\"\n",
    "        n, m = len(num1), len(num2)\n",
    "        i, j = n - 1, m - 1\n",
    "        carry = 0\n",
    "        while i >= 0 and j >= 0:\n",
    "            tmp = int(num1[i]) + int(num2[j]) + carry\n",
    "            carry = 1 if tmp >= 10 else 0\n",
    "            tmp %= 10\n",
    "            ans += str(tmp)\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "\n",
    "        while i >= 0:\n",
    "            tmp = int(num1[i]) + carry\n",
    "            carry = 1 if tmp >= 10 else 0\n",
    "            tmp %= 10\n",
    "            ans += str(tmp)\n",
    "            i -= 1\n",
    "        while j >= 0:\n",
    "            tmp = int(num2[j]) + carry\n",
    "            carry = 1 if tmp >= 10 else 0\n",
    "            tmp %= 10\n",
    "            ans += str(tmp)\n",
    "            j -= 1\n",
    "        if carry == 1:\n",
    "            ans += \"1\"\n",
    "        return ans[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        sys.set_int_max_str_digits(10000)\n",
    "        total = int(num1) + int(num2)\n",
    "\n",
    "        return str(total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = ''\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return '1' + res if carry else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return \"1\" + res if carry else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = ''\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return '1' + res if carry else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = ''\n",
    "        i, j, carry = len(num1)-1, len(num2)-1, 0\n",
    "        while i>=0 or j>=0:\n",
    "            n1 = int(num1[i]) if i>=0 else 0\n",
    "            n2 = int(num2[j]) if j>=0 else 0\n",
    "            tmp_val = n1 + n2 + carry\n",
    "            carry = tmp_val//10\n",
    "            tmp_val = tmp_val%10\n",
    "            res += str(tmp_val)\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        if carry>0:\n",
    "            res += '1'\n",
    "        res = res[::-1]\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i,j,p=len(num1)-1,len(num2)-1,0\n",
    "        ans=''\n",
    "        while i>=0 or j>=0:\n",
    "            n1=int(num1[i]) if i>=0 else 0\n",
    "            n2=int(num2[j]) if j>=0 else 0\n",
    "            s=n1+n2+p\n",
    "            p=s//10\n",
    "            ans=str(s%10)+ans\n",
    "            i,j=i-1,j-1\n",
    "        return '1'+ans if p else ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return \"1\" + res if carry else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        sys.set_int_max_str_digits(10**5)\n",
    "        return str(int(num1)+int(num2))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        len1 = len(num1)\n",
    "        len2 = len(num2)\n",
    "        index1 = len1 - 1\n",
    "        index2 = len2 - 1\n",
    "        count = 0\n",
    "        while index1>=0 or index2>=0:\n",
    "            n1 = int(num1[index1]) if index1 >= 0 else 0\n",
    "            n2 = int(num2[index2]) if index2 >= 0 else 0\n",
    "            s = n1 + n2 + count\n",
    "            val = str(s % 10)\n",
    "            count = s//10\n",
    "            res = val + res\n",
    "            index1 -= 1\n",
    "            index2 -= 1\n",
    "        return \"1\" + res if count else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i = len(num1) - 1\n",
    "        j = len(num2) - 1\n",
    "        carry = 0\n",
    "        new_num = \"\"\n",
    "        while i >= 0 or j >= 0 or carry >= 1:\n",
    "            n1 = 0 if i < 0 else int(num1[i])\n",
    "            n2 = 0 if j < 0 else int(num2[j])\n",
    "            s = n1 + n2 + carry\n",
    "            carry, n = divmod(s, 10)\n",
    "            new_num = str(n) + new_num\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return new_num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        num1 = (len(num2)-len(num1))*'0' + num1\n",
    "        num2 = (len(num1)-len(num2))*'0' + num2\n",
    "        lens = len(num1)\n",
    "        num1 = num1[::-1]\n",
    "        num2 = num2[::-1]\n",
    "        shang = 0\n",
    "        str1 = ''\n",
    "        for i in range(lens):\n",
    "            sum1 = int(num1[i]) + int(num2[i]) + shang\n",
    "            yvshu = sum1 % 10\n",
    "            shang = sum1 // 10\n",
    "            if i != lens -1 :\n",
    "                str1 = str(yvshu) + str1\n",
    "            else:\n",
    "                str1 = str(sum1) + str1\n",
    "        return str1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = ''\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return '1' + res if carry else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i = len(num1)-1\n",
    "        j = len(num2)-1\n",
    "        res = \"\"\n",
    "        carry = 0\n",
    "        while i >=0 or j >= 0:\n",
    "            n1 = num1[i] if i >= 0 else '0'\n",
    "            n2 = num2[j] if j >= 0 else '0'\n",
    "            temp = ord(n1) + ord(n2) - 2*ord('0') + carry\n",
    "            cur = temp%10 \n",
    "            carry = temp//10\n",
    "            res = chr(cur+48) + res\n",
    "            i -= 1\n",
    "            j -= 1 \n",
    "        return '1' + res if carry != 0 else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return \"1\" + res if carry else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n1 = len(num1)\n",
    "        n2 = len(num2)\n",
    "        i = n1 - 1\n",
    "        j = n2 - 1\n",
    "        res = []\n",
    "        carry = 0\n",
    "        while i >= 0 or j >= 0 or carry:\n",
    "            d1 = int(num1[i]) if i >= 0 else 0\n",
    "            d2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = d1 + d2 + carry\n",
    "            res.append('%d'%(tmp % 10))\n",
    "            carry = tmp // 10\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return \"\".join(res[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n1 = len(num1)\n",
    "        n2 = len(num2)\n",
    "        i, j = n1-1, n2-1\n",
    "        ans = \"\"\n",
    "        to_add = 0\n",
    "        while i >= 0 or j >=0:\n",
    "\n",
    "            n1 = int(num1[i]) if i >=0 else 0\n",
    "            n2 = int(num2[j]) if j >=0 else 0\n",
    "            temp = n1 + n2 + to_add\n",
    "            to_add = temp // 10\n",
    "            ans = str(temp % 10) + ans\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "\n",
    "        return ans if to_add == 0 else \"1\" + ans\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        p1 = len(num1) - 1\n",
    "        p2 = len(num2) - 1\n",
    "        res = \"\"\n",
    "        carry = 0\n",
    "\n",
    "        while p1 >= 0 and p2 >= 0:\n",
    "            n1 = int(num1[p1])\n",
    "            n2 = int(num2[p2])\n",
    "            temp = n1 + n2 + carry\n",
    "            carry = temp // 10\n",
    "            res = str(temp % 10) + res\n",
    "            p1 -= 1\n",
    "            p2 -= 1\n",
    "\n",
    "        if p1 >= 0:\n",
    "            for i in range(p1, -1, -1):\n",
    "                temp = int(num1[i]) + carry\n",
    "                carry = temp // 10\n",
    "                res = str(temp % 10) + res\n",
    "        if p2 >= 0:\n",
    "            for i in range(p2, -1, -1):\n",
    "                temp = int(num2[i]) + carry\n",
    "                carry = temp // 10\n",
    "                res = str(temp % 10) + res\n",
    "\n",
    "        if carry != 0:\n",
    "            res = '1' + res\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "\n",
    "        res = \"\"\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "\n",
    "        return \"1\" + res if carry else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        sys.set_int_max_str_digits(50000)\n",
    "        return str(int(num1) +int(num2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i, j = len(num1) - 1, len(num2) - 1\n",
    "        add = 0\n",
    "        res = \"\"\n",
    "        while i >= 0 or j >= 0:\n",
    "            x = int(num1[i]) if i >= 0 else 0\n",
    "            y = int(num2[j]) if j >= 0 else 0\n",
    "            result = x + y + add\n",
    "            res = str(result % 10) + res\n",
    "            add = result // 10\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return \"1\" + res if add else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        plus = 0\n",
    "        res = ''\n",
    "        i = len(num1) - 1\n",
    "        j = len(num2) - 1\n",
    "        while i >= 0 or j >= 0 or plus > 0:\n",
    "            x = 0\n",
    "            if i >= 0:\n",
    "                x = int(num1[i])\n",
    "            y = 0\n",
    "            if j >= 0:\n",
    "                y = int(num2[j])\n",
    "            sum = x + y + plus\n",
    "            if sum >= 10:\n",
    "                sum = sum % 10\n",
    "                plus = 1\n",
    "            else:\n",
    "                plus = 0\n",
    "            res = str(sum) + res\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i,j=len(num1)-1,len(num2)-1\n",
    "        res=\"\"\n",
    "        carry=0\n",
    "        while i>=0 or j>=0:\n",
    "            n1=int(num1[i]) if i>=0 else 0\n",
    "            n2=int(num2[j]) if j>=0 else 0\n",
    "            temp=n1 + n2 +carry\n",
    "            carry = temp //10\n",
    "            res = str(temp%10) + res\n",
    "            i,j = i-1, j-1\n",
    "        return \"1\"+res if carry else res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        ans = ''\n",
    "        i,j, carry = len(num1)-1, len(num2)-1 ,0\n",
    "\n",
    "        while i>=0 or j>=0:\n",
    "            n1 = int(num1[i]) if i>=0 else 0\n",
    "            n2 = int(num2[j]) if j>=0 else 0\n",
    "\n",
    "            temp = n1 + n2 + carry\n",
    "            carry = temp // 10\n",
    "            ans = str(temp%10) + ans\n",
    "            i ,j = i-1 , j-1\n",
    "\n",
    "        if carry !=0:\n",
    "            return '1'+ans\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, n1: str, n2: str) -> str:\n",
    "        s=''\n",
    "        a=max(len(n1),len(n2))\n",
    "        n1,n2,t=n1.rjust(a,'0'),n2.rjust(a,'0'),0\n",
    "        n1,n2=list(n1),list(n2)\n",
    "        for i in range(a-1,-1,-1):\n",
    "            m=eval(n1[i])+eval(n2[i])+t\n",
    "            if m>9:\n",
    "                s=str(m-10)+s\n",
    "                t=1\n",
    "            else:\n",
    "                s=str(m)+s\n",
    "                t=0\n",
    "        if t==1:\n",
    "            s='1'+s\n",
    "        return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        n1 = len(num1)-1\n",
    "        n2 = len(num2)-1\n",
    "        carry = 0\n",
    "        res = ''\n",
    "        while n1>=0 or n2 >=0:\n",
    "            a = '0' if n1<0 else num1[n1]\n",
    "            b = '0' if n2<0 else num2[n2]\n",
    "            tmp = int(a)+int(b)+carry\n",
    "            carry = tmp//10\n",
    "            res = str(tmp%10) + res\n",
    "            n1-=1\n",
    "            n2-=1\n",
    "        \n",
    "        if carry>0:\n",
    "            res = '1' + res\n",
    "        return res\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        # 1、倒序看 \n",
    "        # 2、用divmod对10求余数和商，最后再考虑进位\n",
    "\n",
    "        # res = ''\n",
    "        # count = 0\n",
    "        # i = len(num1) - 1\n",
    "        # j = len(num2) - 1\n",
    "        # while i >= 0 or j >= 0:\n",
    "        #     tmp1 = int(num1[i]) if i >= 0 else 0\n",
    "        #     tmp2 = int(num2[j]) if j >= 0 else 0\n",
    "        #     count, tmp = divmod(tmp1+tmp2+count, 10)\n",
    "        #     res = str(tmp) + res\n",
    "        #     i -= 1\n",
    "        #     j -= 1\n",
    "        # return '1' + res if count else res\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        res = '' \n",
    "        count = 0\n",
    "        i = len(num1) - 1 \n",
    "        j = len(num2) - 1\n",
    "        while i >= 0 or j >= 0:\n",
    "            tmp1 = int(num1[i]) if i >= 0 else 0 \n",
    "            tmp2 = int(num2[j]) if j >= 0 else 0 \n",
    "            count, tmp = divmod(tmp1+tmp2+count, 10) \n",
    "            res = str(tmp) + res \n",
    "            i -= 1\n",
    "            j -= 1 \n",
    "        return '1' + res if count else res \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        if not num1 and not num2:\n",
    "            return ''\n",
    "        if not num1:\n",
    "            return num2\n",
    "        if not num2:\n",
    "            return num1\n",
    "        num1 = num1[::-1]\n",
    "        num2 = num2[::-1]\n",
    "        i = 0\n",
    "        j = 0\n",
    "        res = ''\n",
    "        int_part = 0\n",
    "        while i < len(num1) or j < len(num2):\n",
    "            while i < len(num1) and j < len(num2):\n",
    "                s = int(num1[i]) + int(num2[j]) + int_part\n",
    "                int_part = s // 10\n",
    "                if s >= 10:\n",
    "                    res += str(s % 10)\n",
    "                else:\n",
    "                    res += str(s)\n",
    "                i += 1\n",
    "                j += 1\n",
    "            while i < len(num1):\n",
    "                s1 = int(num1[i]) + int_part\n",
    "                int_part = s1 // 10\n",
    "                if s1 >= 10:\n",
    "                    res += str(s1 % 10)\n",
    "                else:\n",
    "                    res += str(s1)\n",
    "                i += 1\n",
    "            while j < len(num2):\n",
    "                s2 = int(num2[j]) + int_part\n",
    "                int_part = s2 // 10\n",
    "                if s2 >= 10:\n",
    "                    res += str(s2 % 10)\n",
    "                else:\n",
    "                    res += str(s2)\n",
    "                j += 1\n",
    "        if int_part != 0:\n",
    "            res += str(int_part)\n",
    "        return res[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j = len(num1) - 1, len(num2) - 1\n",
    "        carry, sum = 0, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            sum = n1 + n2 + carry\n",
    "            carry = sum // 10\n",
    "            res = str(sum % 10) + res\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        return(\"1\" + res if carry else res)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        l1, l2 = len(num1), len(num2)\n",
    "        if l1 < l2:\n",
    "            num1 = '0' * (l2 - l1) + num1\n",
    "        else:\n",
    "            num2 = '0' * (l1 - l2) + num2\n",
    "        jinwei, ans = 0, \"\"\n",
    "        for i in range(max(l1, l2) - 1, -1, -1):\n",
    "            tmp = ord(num1[i]) + ord(num2[i]) - 96 + jinwei\n",
    "            if tmp >= 10:\n",
    "                ans = str(tmp - 10) + ans\n",
    "                jinwei = 1\n",
    "            else:\n",
    "                ans = str(tmp) + ans\n",
    "                jinwei = 0\n",
    "        if jinwei == 1:\n",
    "            ans = '1' + ans\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        num1 = num1[::-1]\n",
    "        num2 = num2[::-1]\n",
    "        i = 0\n",
    "        len_1, len_2 = len(num1), len(num2)\n",
    "        jinwei = 0\n",
    "        result = \"\"\n",
    "        while i < len_1 and i < len_2:\n",
    "            temp = jinwei + int(num1[i]) + int(num2[i])\n",
    "            jinwei = temp // 10\n",
    "            result = str(temp % 10) + result\n",
    "            i += 1\n",
    "        \n",
    "        temp_ = num1 if len_1 > len_2 else num2\n",
    "        for j in range(i, len(temp_)):\n",
    "            temp = jinwei + int(temp_[j])\n",
    "            jinwei = temp // 10\n",
    "            result = str(temp % 10) + result\n",
    "        \n",
    "        if jinwei:\n",
    "            result = '1' + result\n",
    "        return result\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        p1 = len(num1) - 1\n",
    "        p2 = len(num2) - 1\n",
    "        res = \"\"\n",
    "        carry = 0\n",
    "\n",
    "        while p1 >= 0 and p2 >= 0:\n",
    "            n1 = int(num1[p1])\n",
    "            n2 = int(num2[p2])\n",
    "            temp = n1 + n2 + carry\n",
    "            carry = temp // 10\n",
    "            res = str(temp % 10) + res\n",
    "            p1 -= 1\n",
    "            p2 -= 1\n",
    "\n",
    "        if p1 >= 0:\n",
    "            for i in range(p1, -1, -1):\n",
    "                temp = int(num1[i]) + carry\n",
    "                carry = temp // 10\n",
    "                res = str(temp % 10) + res\n",
    "        if p2 >= 0:\n",
    "            for i in range(p2, -1, -1):\n",
    "                temp = int(num2[i]) + carry\n",
    "                carry = temp // 10\n",
    "                res = str(temp % 10) + res\n",
    "\n",
    "        if carry != 0:\n",
    "            res = str(carry) + res\n",
    "\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return \"1\" + res if carry else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = ''\n",
    "        i, j, carry = len(num1)-1, len(num2)-1, 0\n",
    "        while i>=0 or j>=0:\n",
    "            n1 = int(num1[i]) if i>=0 else 0\n",
    "            n2 = int(num2[j]) if j>=0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        return '1' + res if carry else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = \"\"\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0\n",
    "        while i >= 0 or j >= 0:\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            tmp = n1 + n2 + carry\n",
    "            carry = tmp // 10\n",
    "            res = str(tmp % 10) + res\n",
    "            i, j = i - 1, j - 1\n",
    "        \n",
    "        return \"1\" + res if carry else res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res=''\n",
    "\n",
    "        i,j=len(num1)-1,len(num2)-1\n",
    "        carry=0\n",
    "\n",
    "        while i>=0 or j>=0:\n",
    "            x = int(num1[i]) if i >= 0 else 0\n",
    "            y = int(num2[j]) if j >= 0 else 0\n",
    "\n",
    "            tmp=x+y+carry\n",
    "\n",
    "            carry=tmp//10\n",
    "            dig=tmp%10\n",
    "\n",
    "            res=str(dig)+res\n",
    "\n",
    "            i, j = i - 1, j - 1\n",
    "\n",
    "        # return \"1\" + res if carry else res\n",
    "        if carry==0:return res\n",
    "        else:return '1'+res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i, j = len(num1) - 1, len(num2) - 1\n",
    "        ans = \"\"\n",
    "        flag = 0\n",
    "        while(i >= 0 or j >= 0 or flag):\n",
    "            n1 = int(num1[i]) if i >= 0 else 0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0\n",
    "            sum = n1 + n2\n",
    "            \n",
    "            cur = (sum % 10 + flag) % 10\n",
    "            ans += str(cur)\n",
    "            print (cur)\n",
    "\n",
    "            flag = (sum + flag) // 10\n",
    "            print(sum, flag)\n",
    "            i-=1\n",
    "            j-=1\n",
    "        \n",
    "        return ans[::-1] if not flag else '1' + ans[::-1] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        # num1 位数\n",
    "        digit1 = len(num1) - 1\n",
    "        # num2 位数\n",
    "        digit2 = len(num2) - 1\n",
    "\n",
    "        # 进位\n",
    "        carry = 0\n",
    "        # sum 存储反向结果\n",
    "        sum = []\n",
    "        # 逆序相加\n",
    "        while carry > 0 or digit1 >= 0 or digit2 >= 0:\n",
    "            # 获取对应位数上的数字\n",
    "            num1_d = int(num1[digit1]) if digit1 >= 0 else 0\n",
    "            num2_d = int(num2[digit2]) if digit2 >= 0 else 0\n",
    "            digit1 -= 1\n",
    "            digit2 -= 1\n",
    "            # 计算结果，存储，进位\n",
    "            num = num1_d+num2_d+carry\n",
    "            sum.append('%d'%(num%10))\n",
    "            carry = num // 10\n",
    "        # 返回计算结果\n",
    "        return \"\".join(sum[::-1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        carry = 0\n",
    "        p1, p2 = len(num1) - 1, len(num2) - 1\n",
    "        strs = []\n",
    "        while carry or p1 >= 0 or p2 >= 0:\n",
    "            v = carry\n",
    "            if p1 >= 0:\n",
    "                v += int(num1[p1])\n",
    "                p1 -= 1\n",
    "            if p2 >= 0:\n",
    "                v += int(num2[p2])\n",
    "                p2 -= 1\n",
    "\n",
    "            carry, v = divmod(v, 10)\n",
    "            strs.append(str(v))\n",
    "        return ''.join(reversed(strs))\n",
    "\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i,j = len(num1)-1,len(num2)-1\n",
    "        ans = []\n",
    "        c = 0\n",
    "        while i >= 0 or j >= 0 or c:\n",
    "            a = 0 if i < 0 else int(num1[i])\n",
    "            b = 0 if j < 0 else int(num2[j])\n",
    "            c,v = divmod(a +b+c,10)\n",
    "            ans.append(str(v))\n",
    "            i,j = i-1,j-1\n",
    "        return \"\".join(ans[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        m, n = len(num1), len(num2)\n",
    "        reminder = 0\n",
    "        i, j = m - 1, n - 1\n",
    "        char_list = []\n",
    "        while i >= 0 or j >= 0 or reminder:\n",
    "            if i >= 0:\n",
    "                reminder += int(num1[i])\n",
    "                i -= 1\n",
    "            if j >= 0:\n",
    "                reminder += int(num2[j])\n",
    "                j -= 1\n",
    "            char_list.append(str(reminder % 10))\n",
    "            reminder = reminder // 10\n",
    "        return ''.join(char_list[::-1])\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        index_1 = len(num1) - 1\n",
    "        index_2 = len(num2) - 1\n",
    "        carry = 0\n",
    "        res = []\n",
    "        while index_1 >= 0 or index_2 >= 0 or carry > 0:\n",
    "            num1_d = int(num1[index_1]) if index_1 >= 0 else 0\n",
    "            num2_d = int(num2[index_2]) if index_2 >= 0 else 0\n",
    "            index_1 -= 1\n",
    "            index_2 -= 1\n",
    "            num = num1_d + num2_d + carry\n",
    "            res.append(str(num % 10))\n",
    "            carry = num//10\n",
    "        return \"\".join(res[::-1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "   \n",
    "\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i = len(num1) - 1\n",
    "        j = len(num2) - 1\n",
    "        tempt = 0\n",
    "        ans = \"\"\n",
    "        counnt = 1\n",
    "        while(i >= 0 and j >= 0 ):\n",
    "            n1 = int(num1[i])\n",
    "            n2 = int(num2[j])\n",
    "            rete = (n1 + n2 + tempt) % 10\n",
    "            tempt = (n1 + n2 + tempt) // 10\n",
    "           \n",
    "            ans = str(rete) + ans \n",
    "            counnt = counnt * 10\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        if i == -1 :\n",
    "            while (j >= 0 ):\n",
    "                n2 = int(num2[j])\n",
    "                rete = (n2 + tempt) % 10\n",
    "                tempt = (n2 + tempt) // 10\n",
    "                ans = str(rete) + ans\n",
    "                counnt = counnt * 10\n",
    "                j -= 1\n",
    "        elif j == -1:\n",
    "            while (i >= 0 ):\n",
    "                n1 = int(num1[i])\n",
    "                rete = (n1 + tempt) % 10\n",
    "                tempt = (n1 + tempt) // 10\n",
    "                ans = str(rete) + ans\n",
    "                counnt = counnt * 10\n",
    "                i -= 1\n",
    "        if(tempt == 1):\n",
    "            return  \"1\"+ans\n",
    "        else:\n",
    "            return ans\n",
    "\n",
    "\n",
    "        \n",
    "\n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        len1, len2 = len(num1), len(num2);\n",
    "        l = max(len1, len2)\n",
    "        num1, num2, num = num1.zfill(l)[::-1], num2.zfill(l)[::-1], [\"0\"]\n",
    "        for i in range(l):\n",
    "            if len(num[-1]) == 2:\n",
    "                num[-1] = num[-1][1]\n",
    "                num.append(str(int(num1[i]) + int(num2[i]) + 1))\n",
    "            else:\n",
    "                num.append(str(int(num1[i]) + int(num2[i])))\n",
    "        return ''.join(num[:0:-1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        # 让 num1 总是更长的一个\n",
    "        if len(num2) > len(num1):\n",
    "            num1, num2 = num2, num1\n",
    "\n",
    "        # 将 num2 用 0 填充，使其与 num1 的长度相同\n",
    "        num2 = num2.zfill(len(num1))\n",
    "\n",
    "        carry = 0  # 进位\n",
    "        result = []\n",
    "\n",
    "        for i in range(len(num1) - 1, -1, -1):\n",
    "            temp_sum = int(num1[i]) + int(num2[i]) + carry\n",
    "            result.append(str(temp_sum % 10))\n",
    "            carry = temp_sum // 10\n",
    "\n",
    "        if carry:  # 如果还有剩余的进位\n",
    "            result.append(str(carry))\n",
    "\n",
    "        return ''.join(result[::-1])  # 反转字符串并合并\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = []\n",
    "        p1, p2 = len(num1) - 1, len(num2) - 1\n",
    "        carry = 0\n",
    "\n",
    "        while p1 >= 0 and p2 >= 0:\n",
    "            cur = carry + int(num1[p1]) + int(num2[p2])\n",
    "            carry = cur // 10\n",
    "            cur = cur % 10\n",
    "            res.append(str(cur))\n",
    "            p1 -= 1\n",
    "            p2 -= 1\n",
    "        \n",
    "        while p1 >= 0:\n",
    "            cur = carry + int(num1[p1])\n",
    "            carry = cur // 10\n",
    "            cur = cur % 10\n",
    "            res.append(str(cur))\n",
    "            p1 -= 1\n",
    "        \n",
    "        while p2 >= 0:\n",
    "            cur = carry + int(num2[p2])\n",
    "            carry = cur // 10\n",
    "            cur = cur % 10\n",
    "            res.append(str(cur))\n",
    "            p2 -= 1\n",
    "        if carry:\n",
    "            res.append(str(carry))\n",
    "        return ''.join(res[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\r\n",
    "        result=''\r\n",
    "        up=0\r\n",
    "        i,j=len(num1)-1,len(num2)-1\r\n",
    "        while i >= 0 and j >= 0:\r\n",
    "            a,b=int(num1[i]),int(num2[j])\r\n",
    "            c=a+b+up\r\n",
    "            result=str(c%10)+result\r\n",
    "            up=c//10\r\n",
    "            i-=1\r\n",
    "            j-=1\r\n",
    "        while i >= 0:\r\n",
    "            a=int(num1[i])\r\n",
    "            c=a+up\r\n",
    "            result=str(c%10)+result\r\n",
    "            up=c//10\r\n",
    "            i-=1\r\n",
    "        while j >= 0:\r\n",
    "            b=int(num2[j])\r\n",
    "            c=b+up\r\n",
    "            result=str(c%10)+result\r\n",
    "            up=c//10\r\n",
    "            j-=1\r\n",
    "        return '1'+result if up == 1 else result\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        idx = 0\n",
    "        curr_logit = 0\n",
    "        next_logit = 0\n",
    "        out = []\n",
    "        while 1:\n",
    "            idx1 = len(num1)-1-idx\n",
    "            idx2 = len(num2)-1-idx\n",
    "            n1 = 0\n",
    "            n2 = 0\n",
    "            if idx1 <0 and idx2<0:break\n",
    "            if idx1>=0:\n",
    "                n1 = int(num1[idx1])\n",
    "            if idx2>=0:\n",
    "                n2 = int(num2[idx2])\n",
    "            total = next_logit + n1 + n2\n",
    "            curr_logit = total%10\n",
    "            next_logit = int((total - curr_logit)/10)\n",
    "            out.append(str(curr_logit))\n",
    "            idx +=1\n",
    "        if next_logit>0:\n",
    "            out.append(str(next_logit))\n",
    "        return ''.join(out[::-1])\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        add = 0\n",
    "        ans = []\n",
    "        m, n = len(num1)-1, len(num2)-1\n",
    "        while m>-1 or n>-1 or add>0:\n",
    "            x = int(num1[m]) if m>=0 else 0\n",
    "            y = int(num2[n]) if n>=0 else 0\n",
    "            val = x+y+add\n",
    "            ans.append(str(val%10))\n",
    "            add = val//10\n",
    "            m-=1\n",
    "            n-=1\n",
    "        if add>0:\n",
    "            ans.append(str(add))\n",
    "        return ''.join(ans[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        if len(num1) > len(num2):\n",
    "            return self.addStrings(num2,num1)\n",
    "        \n",
    "        nums1 = [int(i) for i in num1]\n",
    "        nums2 = [int(i) for i in num2]\n",
    "        tmp = [0] * (len(nums2) - len(num1))\n",
    "        nums1 = tmp + nums1\n",
    "        addition = 0\n",
    "        ans = []\n",
    "        for i in range(len(nums2)-1, -1 ,-1):\n",
    "            # print(f'nums1 : {nums1[i]} + nums2 : {nums2[i]}')\n",
    "            if nums1[i] + nums2[i] + addition >= 10:\n",
    "                \n",
    "                ans.append(str(nums1[i] + nums2[i] + addition - 10))\n",
    "                addition = 1\n",
    "            else :\n",
    "                ans.append(str(nums1[i] + nums2[i] + addition))\n",
    "                addition = 0\n",
    "        if addition == 1:\n",
    "            ans.append(str(1))\n",
    "        # print(ans)\n",
    "        s = \"\".join(ans[::-1])\n",
    "        \n",
    "\n",
    "        return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        add = 0\n",
    "        ans = []\n",
    "        m, n = len(num1)-1, len(num2)-1\n",
    "        while m>-1 or n>-1 or add>0:\n",
    "            x = int(num1[m]) if m>=0 else 0\n",
    "            y = int(num2[n]) if n>=0 else 0\n",
    "            val = x+y+add\n",
    "            ans.append(str(val%10))\n",
    "            add = val//10\n",
    "            m-=1\n",
    "            n-=1\n",
    "        return ''.join(ans[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        res = []  # 初始化结果列表\n",
    "        i, j, carry = len(num1) - 1, len(num2) - 1, 0  # i和j分别指向num1和num2的末尾，carry表示进位\n",
    "        while i >= 0 or j >= 0 or carry:  # 只要还有未处理的数字或者进位不为0\n",
    "            n1 = int(num1[i]) if i >= 0 else 0  # 如果i>=0，取num1的第i个字符并转换为整数，否则取0\n",
    "            n2 = int(num2[j]) if j >= 0 else 0  # 如果j>=0，取num2的第j个字符并转换为整数，否则取0\n",
    "            carry, curr = divmod(n1 + n2 + carry, 10)  # 计算和，并得到新的进位和当前位的值\n",
    "            res.append(str(curr))  # 将当前位的值转换为字符串并添加到结果中\n",
    "            i, j = i - 1, j - 1  # 移动i和j\n",
    "        return ''.join(res[::-1])  # 反转结果并将其转换为字符串\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i = len(num1) -1\n",
    "        j = len(num2) -1\n",
    "        c = 0\n",
    "        new_num = ['0']*max(len(num1)+1,len(num2)+1)\n",
    "        index = -1\n",
    "        # print('new_num:',new_num)\n",
    "        while i >= 0 or j >= 0:\n",
    "            value = 0\n",
    "            # print(\"index ={},num1[i]={},num2[j]={},c = {}\".format(index,num1[i],num2[j],c))\n",
    "            if i >= 0:\n",
    "                value = value+int(num1[i])\n",
    "            if j >= 0:\n",
    "                value = value +int(num2[j])\n",
    "            value += c\n",
    "\n",
    "            if value >= 10:\n",
    "                value = value%10\n",
    "                c = 1\n",
    "            else:\n",
    "                c = 0\n",
    "            # print('index:',index)\n",
    "            new_num[index] = str(value)\n",
    "            index -= 1\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "            # print('i,j=',i,j)\n",
    "        #\n",
    "            # print('after:',new_num)\n",
    "        if c != 0:\n",
    "            new_num[index] = str(c)\n",
    "        if new_num[0] =='0':\n",
    "            return \"\".join(new_num[1:])\n",
    "        else:\n",
    "            return \"\".join(new_num)\n",
    "            \n",
    "            \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i,j = len(num1)-1, len(num2)-1\n",
    "        ans = []\n",
    "        c = 0\n",
    "        while i>=0 or j>=0 or c:\n",
    "            a = 0 if i <0 else int(num1[i])\n",
    "            b = 0 if j <0 else int(num2[j])\n",
    "            v = (a+b+c)%10\n",
    "            c = (a+b+c)//10\n",
    "            \n",
    "            ans.append(str(v))\n",
    "            i -=1\n",
    "            j -=1\n",
    "        return \"\".join(ans[::-1])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        if len(num1) > len(num2):\n",
    "            min_num = f'{\"0\"*(len(num1)-len(num2))}{num2}'\n",
    "            max_num = num1\n",
    "        else:\n",
    "            min_num = f'{\"0\"*(len(num2)-len(num1))}{num1}'\n",
    "            max_num = num2\n",
    "        i = len(max_num) - 1\n",
    "        result = []\n",
    "        plus = 0\n",
    "        while i > -1:\n",
    "            tmp = int(max_num[i]) + int(min_num[i]) + plus\n",
    "            value = str(tmp) if tmp < 10 else str(tmp % 10)\n",
    "            result.insert(0, value)\n",
    "            plus = 0 if tmp < 10 else 1\n",
    "            i -= 1\n",
    "        if plus:\n",
    "            result.insert(0, '1')\n",
    "        return ''.join(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i = len(num1) - 1\n",
    "        j = len(num2) - 1\n",
    "        carry = 0\n",
    "        res = []\n",
    "        while i >= 0 or j >= 0:\n",
    "            a = '0' if i<0 else num1[i]\n",
    "            b = '0' if j<0 else num2[j]\n",
    "            tmp = int(a) + int(b) + carry\n",
    "            carry, tmp = tmp//10, tmp%10\n",
    "            res.append(str(tmp))\n",
    "            i-=1\n",
    "            j-=1\n",
    "        \n",
    "        if carry:\n",
    "            res.append('1')\n",
    "        \n",
    "        return \"\".join(res[::-1])\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        m, n = len(num1) - 1, len(num2) - 1\n",
    "        step = 0\n",
    "        s = []\n",
    "        while m >= 0 or n >= 0 or step > 0:\n",
    "            a = int(num1[m]) if m >= 0 else 0\n",
    "            b = int(num2[n]) if n >= 0 else 0\n",
    "            cur = a + b + step\n",
    "            s.append(str(cur % 10))\n",
    "            step = cur // 10\n",
    "            m -=1\n",
    "            n -=1\n",
    "\n",
    "        return \"\".join(reversed(s))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "\n",
    "        n, m = len(num1)-1, len(num2)-1\n",
    "        ans = []\n",
    "        c = 0\n",
    "        while n>-1 or m>-1 or c:\n",
    "            a = 0 if n<0 else int(num1[n])\n",
    "            b = 0 if m<0 else int(num2[m])\n",
    "            c, v = divmod(a+b+c, 10)\n",
    "            ans.append(str(v))\n",
    "            n, m = n-1, m-1\n",
    "        return ''.join(ans[::-1])\n",
    "\n",
    "# class Solution:\n",
    "#     def addStrings(self, num1: str, num2: str) -> str:\n",
    "#         i, j = len(num1) - 1, len(num2) - 1\n",
    "#         ans = []\n",
    "#         c = 0\n",
    "#         while i >= 0 or j >= 0 or c:\n",
    "#             a = 0 if i < 0 else int(num1[i])\n",
    "#             b = 0 if j < 0 else int(num2[j])\n",
    "#             c, v = divmod(a + b + c, 10)\n",
    "#             ans.append(str(v))\n",
    "#             i, j = i - 1, j - 1\n",
    "#         return \"\".join(ans[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        # 反转两个字符串，方便从低位到高位相加\n",
    "        num1 = num1[::-1]\n",
    "        num2 = num2[::-1]\n",
    "\n",
    "        res = [] # 初始化结果字符串\n",
    "        carry = 0 # 初始化进位\n",
    "\n",
    "        # 逐位相加\n",
    "        i= 0\n",
    "        while i <len(num1) or i<len(num2):\n",
    "            # 获取当前位的数字，如果已经超过字符串长度，则默认为0\n",
    "            digit1 = int(num1[i]) if i<len(num1) else 0\n",
    "            digit2 = int(num2[i]) if i<len(num2) else 0\n",
    "            curr_sum = digit1+digit2+carry  # 计算当前位的和，加上进位\n",
    "            carry = curr_sum//10  # 更新进位\n",
    "            res.append(str(curr_sum%10))  # 加入当前值\n",
    "            i += 1\n",
    "        \n",
    "        # 处理最高位的进位\n",
    "        if carry > 0:\n",
    "            res.append(str(carry))\n",
    "        \n",
    "        # 反转结果字符串并返回\n",
    "        res = res[::-1]\n",
    "        return \"\".join(res)\n",
    "        # \"\".join() 是一个字符串方法，用于将一个可迭代对象中的元素连接成一个字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        if len(num2) > len(num1):\n",
    "            num1, num2 = num2, num1\n",
    "        min_length = len(num2)\n",
    "        num1 = list(map(int, num1))[::-1]\n",
    "        num2 = list(map(int, num2))[::-1]\n",
    "        for i in range(min_length):\n",
    "            num1[i] += num2[i]\n",
    "        for i in range(len(num1)):\n",
    "            if i == len(num1) - 1:\n",
    "                if num1[i] > 9:\n",
    "                    num1[i] -= 10\n",
    "                    num1.append(1)\n",
    "            else:\n",
    "                if num1[i] > 9:\n",
    "                    num1[i] -= 10\n",
    "                    num1[i+1] += 1\n",
    "        return ''.join(map(str, num1[::-1]))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "      \n",
    "        l1, l2 = len(num1), len(num2)\n",
    "        i, j = l1-1, l2-1\n",
    "        res = []\n",
    "        c = 0\n",
    "        while i>=0 and j>=0:\n",
    "            r = (int(num1[i]) + int(num2[j]) + c) % 10\n",
    "            c = (int(num1[i]) + int(num2[j]) + c) // 10\n",
    "            res.append(str(r))\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "\n",
    "        while i>=0:\n",
    "            r = (int(num1[i]) + c) % 10 \n",
    "            c = (int(num1[i]) + c) // 10\n",
    "            res.append(str(r))\n",
    "            i -= 1 \n",
    "\n",
    "        while j>=0:\n",
    "            r = (int(num2[j]) + c) % 10 \n",
    "            c = (int(num2[j]) + c) // 10\n",
    "            res.append(str(r))\n",
    "            j -= 1\n",
    "\n",
    "        if c > 0:\n",
    "            res.append(str(c))\n",
    "            \n",
    "        res = res[::-1]\n",
    "        return ''.join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i, j = len(num1) - 1, len(num2) - 1\n",
    "        ans = []\n",
    "        c = 0\n",
    "        while i >= 0 or j >= 0 or c:\n",
    "            a = 0 if i < 0 else int(num1[i])\n",
    "            b = 0 if j < 0 else int(num2[j])\n",
    "            c, v = divmod(a + b +c, 10)\n",
    "            ans.append(str(v))\n",
    "            i, j = i - 1, j - 1\n",
    "        return \"\".join(ans[::-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        max_len = max(len(num1), len(num2))\n",
    "        num1_lst = [int(_) for _ in num1][::-1]\n",
    "        num2_lst = [int(_) for _ in num2][::-1]\n",
    "\n",
    "        carry = 0\n",
    "        r_lst = []\n",
    "        for i in range(max_len):\n",
    "            v1 = num1_lst[i] if i < len(num1_lst) else 0\n",
    "            v2 = num2_lst[i] if i < len(num2_lst) else 0\n",
    "            s = v1 + v2 + carry\n",
    "            r_lst.append(s % 10)\n",
    "            carry = s // 10\n",
    "            if i == max_len - 1 and carry > 0:\n",
    "                r_lst.append(carry)\n",
    "\n",
    "        return ''.join([str(_) for _ in r_lst[::-1]])\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        carry = 0\n",
    "        ans = []\n",
    "        for b1, b2 in zip_longest(reversed(num1), reversed(num2), fillvalue=\"0\"):\n",
    "            r = int(b1) + int(b2) + carry\n",
    "            carry = r >= 10\n",
    "            ans.append(str(r % 10))\n",
    "        \n",
    "        if carry:\n",
    "            ans.append(\"1\")\n",
    "            \n",
    "        return \"\".join(reversed(ans))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i, j = len(num1) - 1, len(num2) - 1\n",
    "        ans = []\n",
    "        c = 0\n",
    "        while i >= 0 or j >= 0 or c:\n",
    "            a = 0 if i < 0 else int(num1[i])\n",
    "            b = 0 if j < 0 else int(num2[j])\n",
    "            c, v = divmod(a + b + c, 10)\n",
    "            ans.append(str(v))\n",
    "            i, j = i - 1, j - 1\n",
    "        return \"\".join(ans[::-1])\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "\n",
    "        # 从最后开始\n",
    "        large = num1 if len(num1) > len(num2) else num2\n",
    "        small = num1 if len(num1) <= len(num2) else num2\n",
    "        large = large[::-1]\n",
    "        small = small[::-1]\n",
    "\n",
    "        carry = 0\n",
    "        output = []\n",
    "        for i in range(len(large)):\n",
    "            l = int(large[i])\n",
    "            s = int(small[i]) if i < len(small) else 0\n",
    "\n",
    "            sum = l + s +carry\n",
    "            output.append(str(sum % 10))\n",
    "            carry = sum // 10\n",
    "        \n",
    "        if carry:\n",
    "            output.append(str(carry))\n",
    "        return \"\".join(output)[::-1]\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addStrings(self, num1: str, num2: str) -> str:\n",
    "        i, j = 0, 0\n",
    "        n, m = len(num1), len(num2)\n",
    "\n",
    "        res = []\n",
    "        \n",
    "        k = 0\n",
    "        while i < n and j < m:\n",
    "            a, b = int(num1[n - i - 1]), int(num2[m - j - 1])\n",
    "            s = a + b + k\n",
    "            k, r = s // 10, s % 10\n",
    "            res.append(str(r))\n",
    "\n",
    "            i += 1\n",
    "            j += 1\n",
    "        \n",
    "        while i < n:\n",
    "            a = int(num1[n - i - 1])\n",
    "            s = a + k\n",
    "            k, r = s // 10, s % 10\n",
    "            res.append(str(r))\n",
    "\n",
    "            i += 1\n",
    "\n",
    "        while j < m:\n",
    "            b = int(num2[m - j - 1])\n",
    "            s = b + k\n",
    "            k, r = s // 10, s % 10\n",
    "            res.append(str(r))\n",
    "\n",
    "            j += 1\n",
    "        \n",
    "        if k:\n",
    "            res.append(str(k))\n",
    "\n",
    "        res.reverse()\n",
    "        return ''.join(res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        t = 0\n",
    "        for i in range(len(num)-1, -1, -1):\n",
    "            t += k % 10\n",
    "            k = k // 10\n",
    "            num[i] += t\n",
    "            t = num[i] // 10\n",
    "            num[i] = num[i] % 10\n",
    "        k += t\n",
    "        while k > 0:\n",
    "            num.insert(0, k % 10)\n",
    "            k //= 10\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "\r\n",
    "    def addToArrayForm(self, num: list[int], k: int) -> list[int]:\r\n",
    "        return list(map(int, str(int(''.join(map(str, num))) + k)))\r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(1000000000)\n",
    "        return list(map(int,str(int(''.join(map(str,num))) + k)))\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        \n",
    "        \n",
    "        return list(map(int, str(int(\"\".join(map(str, num))) + k)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: list[int], k: int):\n",
    "        l = num\n",
    "        i = int(\"\".join([str(i) for i in l]))\n",
    "        x=i+k\n",
    "        result=[]\n",
    "        for i in str(x):\n",
    "            result.append(i)\n",
    "        results = list(map(int, result))\n",
    "        return results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # no need to convert k into list\n",
    "        # no need to create a new list, update the num directly\n",
    "        carry=0\n",
    "        #travsal the list first\n",
    "        for i in range(len(num)-1,-1,-1):\n",
    "            tmp=k%10 # get the last number of K\n",
    "            s=num[i]+tmp+carry\n",
    "            if s <10:\n",
    "                num[i]=s\n",
    "                carry=0\n",
    "            elif s>=10:\n",
    "                num[i]=s%10\n",
    "                carry=1\n",
    "            k//=10 # pop out the last number of K\n",
    "\n",
    "        while k > 0:\n",
    "            s=k%10 + carry\n",
    "            if s>=10:\n",
    "                carry=1\n",
    "                s=s%10  \n",
    "            else:\n",
    "                carry=0\n",
    "            num.insert(0,s)\n",
    "            k//=10\n",
    "        if carry==1:\n",
    "            num.insert(0,1)\n",
    "            \n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # no need to convert k into list\n",
    "        # no need to create a new list, update the num directly\n",
    "        carry=0\n",
    "        #travsal the list first\n",
    "        for i in range(len(num)-1,-1,-1):\n",
    "            # tmp=k%10 # get the last number of K\n",
    "            carry,num[i]=divmod(num[i]+k%10+carry,10) #求和取余数一步搞定\n",
    "            # carry=s//10\n",
    "            # num[i]=s if s<10 else s%10\n",
    "\n",
    "            k//=10 # pop out the last number of K\n",
    "\n",
    "        while k > 0 or carry ==1:\n",
    "            # s=k%10 + carry\n",
    "            # carry=s//10\n",
    "            carry, number = divmod(k%10+carry,10)\n",
    "            # if s >= 10:\n",
    "            #     s=s%10\n",
    "            num.insert(0,number) # insert to first one\n",
    "            k//=10\n",
    "\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "\n",
    "        '按位相加，list保存'\n",
    "        # k = str(k)\n",
    "        # i, j = len(num)-1, len(k)-1\n",
    "        # add = 0\n",
    "        # ans = []\n",
    "        # while i >= 0 or j >= 0 or add != 0:\n",
    "        #     x = num[i] if i >= 0 else 0\n",
    "        #     y = int(k[j]) if j >= 0 else 0\n",
    "        #     result = x + y + add\n",
    "        #     ans.append(result % 10)\n",
    "        #     add = result // 10\n",
    "        #     i -= 1\n",
    "        #     j -= 1\n",
    "        # return ans[::-1]\n",
    "\n",
    "        '直接加'\n",
    "        i = len(num) - 1\n",
    "        while k:\n",
    "            num[i] += k # 用当前位置 直接加上 整个 k\n",
    "            k, num[i] = num[i] // 10, num[i] % 10  # 再保留新当前位的同时 缩小k的范围\n",
    "            i -= 1\n",
    "\n",
    "            if i < 0 and k:\n",
    "                num.insert(0,0)  # 如果数组遍历完了 k还有 则 num往前 扩容 \n",
    "                i = 0\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        string = int(''.join([str(s) for s in num]))\n",
    "        a = eval(f\"{string}+{str(k)}\")\n",
    "        b = []\n",
    "        c = str(a)\n",
    "        for i in c:\n",
    "            b.append(i)\n",
    "        results = list(map(int, b))\n",
    "\n",
    "\n",
    "        return results\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, nums: List[int], k: int) -> List[int]:\n",
    "        i = len(nums) - 1\n",
    "        while k:\n",
    "            nums[i] += k\n",
    "            k, nums[i] = nums[i] // 10, nums[i] % 10\n",
    "            i -= 1\n",
    "            if i < 0 and k:\n",
    "                nums.insert(0, 0)\n",
    "                i = 0\n",
    "        return nums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def addToArrayForm(self, A: List[int], K: int) -> List[int]:\n",
    "\n",
    "        i = len(A) - 1\n",
    "\n",
    "        while K:\n",
    "\n",
    "            A[i] += K\n",
    "\n",
    "            K, A[i] = A[i] // 10, A[i] % 10\n",
    "\n",
    "            i -= 1\n",
    "\n",
    "\n",
    "\n",
    "            if i < 0 and K:\n",
    "\n",
    "                A.insert(0,0)\n",
    "\n",
    "                i = 0\n",
    "\n",
    "        return A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # no need to convert k into list\n",
    "        # no need to create a new list, update the num directly\n",
    "        carry=0\n",
    "        #travsal the list first\n",
    "        for i in range(len(num)-1,-1,-1):\n",
    "            # tmp=k%10 # get the last number of K\n",
    "            carry,num[i]=divmod(num[i]+k%10+carry,10) #求和取余数一步搞定\n",
    "            # carry=s//10\n",
    "            # num[i]=s if s<10 else s%10\n",
    "\n",
    "            k//=10 # pop out the last number of K\n",
    "\n",
    "        while k > 0 or carry ==1:\n",
    "            # s=k%10 + carry\n",
    "            # carry=s//10\n",
    "            carry, number = divmod(k%10+carry,10)\n",
    "            # if s >= 10:\n",
    "            #     s=s%10\n",
    "            num.insert(0,number) # insert to first one\n",
    "            k//=10\n",
    "\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        i = len(num) - 1\n",
    "        while i > -1 and k != 0:\n",
    "            tmp = num[i] + k % 10\n",
    "            num[i] = tmp % 10\n",
    "            k = k // 10 + tmp // 10\n",
    "            i -= 1\n",
    "        while k:\n",
    "            num = [k % 10] + num\n",
    "            k //= 10\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    # def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "    #     x = 0\n",
    "    #     size = len(num) - 1\n",
    "    #     for i in range(len(num)):\n",
    "    #         x += num[i] * pow(10, size - i)   # 当数组长度很大时数据会溢出\n",
    "    #     x += k\n",
    "    #     print(x)\n",
    "    #     ans = []\n",
    "    #     while (x):\n",
    "    #         y = x % 10\n",
    "    #         x //= 10\n",
    "    #         ans.insert(0, y)\n",
    "    #     return ans\n",
    "    # 直接在数组层面上操作\n",
    "     def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        size = len(num) - 1\n",
    "        add = 0\n",
    "        while ((k or add) and size >= 0):   # 避免数组进位导致索引变为-1\n",
    "            x = k % 10\n",
    "            k //= 10\n",
    "            y = num[size] + x + add\n",
    "            num[size] = y % 10\n",
    "            add = y // 10\n",
    "            size -= 1\n",
    "        while (k or add):   # 如果进位或者k没用完，意味着数组进位了\n",
    "            x = k % 10\n",
    "            k //= 10\n",
    "            y = x + add\n",
    "            num.insert(0, y % 10)\n",
    "            add = y // 10\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # sum = 0\n",
    "        # for i in num:\n",
    "        #     sum = sum * 10 + i\n",
    "        # sum = sum + k\n",
    "        # res = []\n",
    "        # while sum:\n",
    "        #     res.append(sum % 10)\n",
    "        #     sum //= 10\n",
    "        # res = res[::-1]\n",
    "        # return res\n",
    "\n",
    "        i = len(num) - 1\n",
    "        while k:\n",
    "            k += num[i]\n",
    "            num[i],k = k % 10,k // 10\n",
    "            i -= 1\n",
    "\n",
    "            if i < 0 and k:\n",
    "                num.insert(0,0)\n",
    "                i = 0\n",
    "        return num\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        cur = len(num)\n",
    "        while k > 0:\n",
    "            cur -= 1\n",
    "\n",
    "            if cur < 0:\n",
    "                num.insert(0,k)\n",
    "                cur = 0\n",
    "            else:\n",
    "                num[cur] += k\n",
    "            k, num[cur] = divmod(num[cur], 10)\n",
    "            \n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        return list(map(int,list(str(int(''.join(list(map(str,num)))) + k))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        i=len(num)-1\n",
    "        while i>=0 and k!=0:\n",
    "            s=num[i]+k%10\n",
    "            num[i]=s%10\n",
    "            k=k//10+s//10\n",
    "            i-=1\n",
    "        while k:\n",
    "            num=[k%10]+num\n",
    "            k=k//10\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # no need to convert k into list\n",
    "        # no need to create a new list, update the num directly\n",
    "        carry=0\n",
    "        #travsal the list first\n",
    "        for i in range(len(num)-1,-1,-1):\n",
    "            tmp=k%10 # get the last number of K\n",
    "            s=num[i]+tmp+carry\n",
    "            carry=s//10\n",
    "            num[i]=s if s<10 else s%10\n",
    "\n",
    "            k//=10 # pop out the last number of K\n",
    "\n",
    "        while k > 0 or carry ==1:\n",
    "            s=k%10 + carry\n",
    "            carry=s//10\n",
    "            if s >= 10:\n",
    "                s=s%10\n",
    "            num.insert(0,s) # insert to first one\n",
    "            k//=10\n",
    "\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        n1,l = 0,len(num)\n",
    "        for i in range(l-1):\n",
    "            n1 += num[i]\n",
    "            n1 *= 10\n",
    "        n2 = n1 + num[-1] + k\n",
    "        ans = []\n",
    "        while n2:\n",
    "            ans = [n2 % 10] + ans\n",
    "            n2 //= 10\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        i = len(num) - 1\n",
    "        while i > -1 and k != 0:\n",
    "            tmp = num[i] + k % 10\n",
    "            num[i] = tmp % 10\n",
    "            k = k // 10 + tmp // 10\n",
    "            i -= 1\n",
    "        while k:\n",
    "            num = [k % 10] + num\n",
    "            k //= 10\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self,A:List[int],K:int)->List[int]:\n",
    "\n",
    "        #将整数K转换为字符串，然后将其每个字符转换为整数并存储在列表K中\n",
    "        K = list(map(int,str(K)))\n",
    "\n",
    "        # 创建一个空列表res用于存储结果，初始化索引i和j以分别从A和K中处理数字\n",
    "        res=[]\n",
    "        i,j = len(A)-1,len(K)-1\n",
    "        carry=0\n",
    "\n",
    "        #通过循环遍历A和K来执行相加操作\n",
    "        while i>=0 and j>=0:\n",
    "\n",
    "            #将A[i]、K[j]、carry相加，并将结果添加到res中\n",
    "            res.append(A[i]+K[j]+carry)\n",
    "\n",
    "            #将res的最有一位限制在0-9之间，将carry更新为res除以10的商\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            i-=1\n",
    "            j-=1\n",
    "\n",
    "        #处理剩余的A中的数字    \n",
    "        while i>=0:\n",
    "            res.append(A[i]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            i-=1\n",
    "        \n",
    "        #处理剩余的K中的数字\n",
    "        while j>=0:\n",
    "            res.append(K[j]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            j-=1\n",
    "\n",
    "        #如果还有进位（carry大于0），则将其添加到结果中    \n",
    "        if carry:\n",
    "            res.append(1)\n",
    "\n",
    "        #返回结果列表，但需要将其逆序以得到正确的顺序\n",
    "        return res[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        i= len(num)-1\n",
    "        while k:\n",
    "            num[i] +=k\n",
    "            k,num[i] = num[i] //10,num[i]%10\n",
    "            i-=1\n",
    "            if i<0 and k:\n",
    "                num.insert(0,0)\n",
    "                i=0\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # no need to convert k into list\n",
    "        # no need to create a new list, update the num directly\n",
    "        carry=0\n",
    "        #travsal the list first\n",
    "        for i in range(len(num)-1,-1,-1):\n",
    "            tmp=k%10 # get the last number of K\n",
    "            s=num[i]+tmp+carry\n",
    "            carry=s//10\n",
    "            num[i]=s if s<10 else s%10\n",
    "\n",
    "            k//=10 # pop out the last number of K\n",
    "\n",
    "        while k > 0:\n",
    "            s=k%10 + carry\n",
    "            carry=s//10\n",
    "            if s >= 10:\n",
    "                s=s%10\n",
    "            num.insert(0,s) # insert to first one\n",
    "            k//=10\n",
    "        # add the last 1 to the first \n",
    "        if carry==1:\n",
    "            num.insert(0,1)\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        i=len(num)-1\n",
    "        while i>=0 and k!=0:\n",
    "            s=num[i]+k%10\n",
    "            num[i]=s%10\n",
    "            k=k//10+s//10\n",
    "            i-=1\n",
    "        while k:\n",
    "            num=[k%10]+num\n",
    "            k=k//10\n",
    "        return num\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        i = len(num) - 1\n",
    "        while i > -1:\n",
    "            tmp = num[i] + k % 10\n",
    "            num[i] = tmp % 10\n",
    "            k = k // 10 + tmp // 10\n",
    "            i -= 1\n",
    "        while k:\n",
    "            num = [k % 10] + num\n",
    "            k //= 10\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        res = []\n",
    "        i = len(num) - 1\n",
    "        jinwei = 0\n",
    "        if i==-1:\n",
    "            while k!=0:\n",
    "                res.append(k%10)\n",
    "                k//=10\n",
    "        while i != -1 or k != 0:\n",
    "            if i != -1 and k != 0:\n",
    "                he = num[i] + k % 10 + jinwei\n",
    "                if he < 10:\n",
    "                    res.append(he)\n",
    "                    jinwei = 0\n",
    "                else:\n",
    "                    res.append(he - 10)\n",
    "                    jinwei = 1\n",
    "                i -= 1\n",
    "                k //= 10\n",
    "            if i != -1 and k==0:\n",
    "                he = num[i] + jinwei\n",
    "                if he < 10:\n",
    "                    res.append(he)\n",
    "                    jinwei = 0\n",
    "                else:\n",
    "                    res.append(he - 10)\n",
    "                    jinwei = 1\n",
    "                i -= 1\n",
    "            if i==-1 and k!=0:\n",
    "                he = k % 10 + jinwei\n",
    "                if he < 10:\n",
    "                    res.append(he)\n",
    "                    jinwei = 0\n",
    "                else:\n",
    "                    res.append(he - 10)\n",
    "                    jinwei = 1\n",
    "                k//=10\n",
    "        if jinwei == 1:\n",
    "            res.append(1)\n",
    "        res.reverse()\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        i=len(num)-1\n",
    "        while k:\n",
    "            num[i]+=k\n",
    "            k,num[i]=num[i]//10,num[i]%10\n",
    "            i-=1\n",
    "            if i<0 and k:\n",
    "                num.insert(0,0)\n",
    "                i=0\n",
    "        return num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        n = len(num)\n",
    "        m = n - 1\n",
    "\n",
    "        res = 0\n",
    "\n",
    "        for i in range(n):\n",
    "            res += 10 ** m * num[i]\n",
    "            m -= 1\n",
    "\n",
    "        res += k\n",
    "        ans = []\n",
    "        while res != 0:\n",
    "            ans.append(res % 10)\n",
    "            res //= 10\n",
    "\n",
    "        ans.reverse()\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        number = 0\n",
    "        for d in num:\n",
    "            number = number * 10 + d\n",
    "        \n",
    "        number += k\n",
    "\n",
    "        res = []\n",
    "        while number > 0:\n",
    "            res.append(number % 10)\n",
    "            number //= 10\n",
    "        \n",
    "        res = list(reversed(res))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        ans=0\n",
    "        for x in num:\n",
    "            ans = 10*ans +x\n",
    "        ans+=k\n",
    "        res=[]\n",
    "        while ans:\n",
    "            a=ans%10\n",
    "            res.append(a)\n",
    "            ans =ans//10\n",
    "        return res[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        dig=0\n",
    "        for i in range(len(num)):\n",
    "            dig=dig*10+num[i]\n",
    "        print(dig)\n",
    "        ans=dig+k\n",
    "        sys.set_int_max_str_digits(20000)\n",
    "        res=[]\n",
    "        for c in str(ans):\n",
    "            res.append(int(c))\n",
    "        print(res)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "sys.set_int_max_str_digits(100000) \n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        num_st=\"\"\n",
    "        for i in num:\n",
    "            num_st=\"\".join((num_st,str(i)))\n",
    "        res=str(int(num_st)+k)\n",
    "        return [int(i) for i in res]\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, A: List[int], K: int) -> List[int]:\n",
    "        i = len(A) - 1\n",
    "        while K:\n",
    "            A[i] += K\n",
    "            K, A[i] = A[i] // 10, A[i] % 10\n",
    "            i -= 1\n",
    "            if i < 0 and K:\n",
    "                A.insert(0,0)\n",
    "                i = 0\n",
    "        return A\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        n = len(num)\n",
    "        ret = 0\n",
    "        ans = []\n",
    "        for i in range(len(num)):\n",
    "            ret += num[i]*10**(n-i-1)\n",
    "        ret += k\n",
    "        while ret:\n",
    "            ans.append(ret%10)\n",
    "            ret = ret // 10\n",
    "        return ans[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        n1,l = 0,len(num)\n",
    "        for i in range(l-1):\n",
    "            n1 += num[i]\n",
    "            n1 *= 10\n",
    "        n2 = n1 + num[-1] + k\n",
    "        ans = []\n",
    "        while n2:\n",
    "            ans.append(n2 % 10)\n",
    "            n2 //= 10\n",
    "        return ans[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        n = len(num)\n",
    "        m = n - 1\n",
    "\n",
    "        res = 0\n",
    "\n",
    "        for i in range(n):\n",
    "            res += 10 ** m * num[i]\n",
    "            m -= 1\n",
    "\n",
    "        res += k\n",
    "        ans = []\n",
    "        while res != 0:\n",
    "            ans.append(res % 10)\n",
    "            res //= 10\n",
    "\n",
    "        ans.reverse()\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, A: List[int], K: int) -> List[int]:\n",
    "        K = list(map(int,str(K)))\n",
    "        \n",
    "        res = []\n",
    "        i,j = len(A)-1,len(K)-1\n",
    "        carry = 0\n",
    "\n",
    "        while i >= 0 and j >= 0:\n",
    "            res.append(A[i] + K[j] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        while i >= 0:\n",
    "            res.append(A[i] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            i -= 1\n",
    "        while j >= 0:\n",
    "            res.append(K[j] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            j -= 1\n",
    "\n",
    "        if carry:\n",
    "            res.append(1)\n",
    "\n",
    "        return res[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, A: List[int], K: int) -> List[int]:\n",
    "        K = list(map(int,str(K)))\n",
    "        \n",
    "        res = []\n",
    "        i,j = len(A)-1,len(K)-1\n",
    "        carry = 0\n",
    "\n",
    "        while i >= 0 and j >= 0:\n",
    "            res.append(A[i] + K[j] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        while i >= 0:\n",
    "            res.append(A[i] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            i -= 1\n",
    "        while j >= 0:\n",
    "            res.append(K[j] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            j -= 1\n",
    "\n",
    "        if carry:\n",
    "            res.append(1)\n",
    "\n",
    "        return res[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        lst = [int(c) for c in str(k)][::-1]\n",
    "        num = num[::-1]\n",
    "        c = 0\n",
    "        la, lb = len(num), len(lst)\n",
    "        if la >= lb:\n",
    "            lst += [0] * (la - lb)\n",
    "        else:\n",
    "            num += [0] * (lb - la)\n",
    "        lm = max(la, lb)\n",
    "        ans = [0] * lm\n",
    "        for i in range(lm):\n",
    "            s = num[i] + lst[i] + c\n",
    "            ans[i] = s % 10\n",
    "            if s >= 10:\n",
    "                c = 1\n",
    "            else:\n",
    "                c = 0\n",
    "        if c == 1:\n",
    "            ans.append(1)\n",
    "        return ans[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(10001)\n",
    "        \n",
    "        n = len(num)\n",
    "        m = n - 1\n",
    "\n",
    "        res = 0\n",
    "\n",
    "        for i in range(n):\n",
    "            res += 10 ** m * num[i]\n",
    "            m -= 1\n",
    "\n",
    "        res += k\n",
    "        return list(map(lambda x: int(x), list(str(res))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, A: List[int], K: int) -> List[int]:\n",
    "        n=len(A)\n",
    "        res = [0]*n\n",
    "        for i,v in enumerate(A[::-1]):\n",
    "            K+=v\n",
    "            res[i]=K%10\n",
    "            K//=10\n",
    "            if K != 0 and i == n - 1:\n",
    "                res+=list(map(int,str(K)[::-1]))\n",
    "        return res[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "\n",
    "    \tres = []\n",
    "    \ti, carry = len(num) - 1, 0\n",
    "    \twhile i >= 0 or k != 0:\n",
    "        \tx = num[i] if i >= 0 else 0\n",
    "        \ty = k % 10 if k != 0 else 0\n",
    "            \n",
    "        \tsum = x + y + carry\n",
    "        \tres.append(sum % 10)\n",
    "        \tcarry = sum // 10\n",
    "\n",
    "        \ti -= 1\n",
    "        \tk //= 10\n",
    "    \tif carry != 0: res.append(carry)\n",
    "    \treturn res[::-1]\n",
    "    \n",
    "    \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        num = num[::-1]\n",
    "        k = str(k)[::-1]\n",
    "        n_len = len(num)\n",
    "        k_len = len(k)\n",
    "\n",
    "        if n_len < k_len:\n",
    "            for count in range(0, k_len - n_len):\n",
    "                num.append(0)\n",
    "        n_len = len(num)\n",
    "        \n",
    "        \n",
    "        for i in range(0, k_len):\n",
    "            date = num[i] + int(k[i])\n",
    "            if date >= 10:\n",
    "                num[i] = int(str(date)[-1])\n",
    "                if i + 1 == n_len:\n",
    "                    num.append(1)\n",
    "                    break \n",
    "                num[i + 1] += 1\n",
    "            else:\n",
    "                num[i] = date\n",
    "\n",
    "        i = 0\n",
    "        while True:\n",
    "        \n",
    "            if num[i] >= 10:\n",
    "                num[i] = int(str(num[i])[-1])\n",
    "                if i == n_len - 1:\n",
    "                    num.append(1)\n",
    "                    return num[::-1]\n",
    "                num[i + 1] += 1\n",
    "\n",
    "            i += 1\n",
    "\n",
    "            if i == n_len:\n",
    "                return num[::-1]\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def addToArrayForm(self, num, k):\n",
    "        \"\"\"\n",
    "        :type num: List[int]\n",
    "        :type k: int\n",
    "        :rtype: List[int]\n",
    "        \"\"\"\n",
    "        k_str = str(k)\n",
    "        carry = 0\n",
    "        result = []\n",
    "        \n",
    "        i = len(num) - 1\n",
    "        j = len(k_str) - 1\n",
    "\n",
    "        while i >= 0 or j >= 0 or carry:\n",
    "            x = num[i] if i >= 0 else 0\n",
    "            y = int(k_str[j]) if j >= 0 else 0\n",
    "            total = x + y + carry\n",
    "            carry = total // 10\n",
    "            result.append(total % 10)\n",
    "            \n",
    "            i -= 1\n",
    "            j -= 1\n",
    "\n",
    "        return result[::-1]  # Reverse the result to get the correct order"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # count = 0\n",
    "        # for n in num:\n",
    "        #     count = count * 10 + n\n",
    "        # ret = []\n",
    "        # for c in str(count + k):\n",
    "        #     ret.append(int(c))\n",
    "        # return ret\n",
    "\n",
    "        # 新数字\n",
    "        ad = []\n",
    "        for ch in str(k):\n",
    "            ad.append(int(ch))\n",
    "        # 补齐位数\n",
    "        ln, la = len(num), len(ad)\n",
    "        if ln > la:\n",
    "            ad = [0] * (ln - la) + ad\n",
    "            maxl = ln\n",
    "        elif ln < la:\n",
    "            num = [0] * (la - ln) + num\n",
    "            maxl = la\n",
    "        else:\n",
    "            maxl = ln\n",
    "        #\n",
    "        # l = max(ln, la)\n",
    "        u = 0\n",
    "        ret = []\n",
    "        for i in range(-1, -maxl - 1, -1):\n",
    "            n = int(num[i]) + int(ad[i]) + u\n",
    "            ret.append(n % 10)\n",
    "            u = n // 10\n",
    "        if u == 1:\n",
    "            ret.append(1)\n",
    "        ret.reverse()\n",
    "        return ret\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "\n",
    "        i = len(num) - 1\n",
    "        nxt = 0\n",
    "        ans = []\n",
    "        while k or nxt != 0 or i >= 0:\n",
    "            if k > 0:\n",
    "                cur_k = k % 10\n",
    "            else:\n",
    "                cur_k = 0\n",
    "            if i >= 0:\n",
    "                cur_num = num[i]\n",
    "            else:\n",
    "                cur_num = 0\n",
    "\n",
    "            cur_ans = cur_k + cur_num + nxt\n",
    "            if cur_ans > 9:\n",
    "                cur_ans = cur_ans - 10\n",
    "                ans.append(cur_ans)\n",
    "                nxt = 1\n",
    "            else:\n",
    "                ans.append(cur_ans)\n",
    "                nxt = 0\n",
    "\n",
    "            k = k // 10\n",
    "            i -= 1\n",
    "        return ans[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "def list2int(lst: List[int]) -> int:\n",
    "    res: int = 0\n",
    "    for i in range(len(lst)):\n",
    "        res += 10 ** i * lst[-i-1]\n",
    "    return res\n",
    "\n",
    "\n",
    "def int2list(integer: int) -> List[int]:\n",
    "    res: List[int] = []\n",
    "    while integer != 0:\n",
    "        temp = integer // 10\n",
    "        res.append(integer - temp * 10)\n",
    "        integer = temp\n",
    "    return res[::-1]\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        return int2list(list2int(num) + k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # num_k = list(map(int, list(str(k))))[::-1]\n",
    "        # num = num[::-1]\n",
    "        # i = m = 0\n",
    "        # res = []\n",
    "        # while i < len(num) or i < len(num_k) or m:\n",
    "        #     m += num[i] if i < len(num) else 0\n",
    "        #     m += num_k[i] if i < len(num_k) else 0\n",
    "        #     res.append(m%10)\n",
    "        #     m //= 10\n",
    "        #     i += 1\n",
    "        # return res[::-1]\n",
    "\n",
    "        # ---------------------------------\n",
    "        i, m = len(num)-1, 0\n",
    "        res = []\n",
    "        while i >= 0 or k or m:\n",
    "            m += num[i] if i >= 0 else 0\n",
    "            m += k % 10\n",
    "            res.append(m%10)\n",
    "            m //= 10\n",
    "            k //= 10\n",
    "            i -= 1\n",
    "        return res[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self,A:List[int],K:int)->List[int]:\n",
    "        #将整数K转换为字符串\n",
    "        K = list(map(int,str(K)))\n",
    "        res=[]\n",
    "        i,j = len(A)-1,len(K)-1\n",
    "        carry=0\n",
    "        while i>=0 and j>=0:\n",
    "            res.append(A[i]+K[j]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            i-=1\n",
    "            j-=1\n",
    "        while i>=0:\n",
    "            res.append(A[i]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            i-=1\n",
    "        while j>=0:\n",
    "            res.append(K[j]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            j-=1\n",
    "        if carry:\n",
    "            res.append(1)\n",
    "        return res[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        num_int = 0\n",
    "        for i in range(1, len(num)+1):  # 将 num 列表转换成整数\n",
    "            num_int += num[-i] * pow(10, i-1)\n",
    "        num_int += k  # 与 k 相加\n",
    "        num_list = []\n",
    "        while num_int:  # 再转换成列表\n",
    "            num_list.append(num_int % 10)\n",
    "            num_int = num_int // 10\n",
    "        return num_list[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self,A:List[int],K:int)->List[int]:\n",
    "        #将整数K\n",
    "        K = list(map(int,str(K)))\n",
    "        res=[]\n",
    "        i,j = len(A)-1,len(K)-1\n",
    "        carry=0\n",
    "        while i>=0 and j>=0:\n",
    "            res.append(A[i]+K[j]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            i-=1\n",
    "            j-=1\n",
    "        while i>=0:\n",
    "            res.append(A[i]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            i-=1\n",
    "        while j>=0:\n",
    "            res.append(K[j]+carry)\n",
    "            res[-1],carry=res[-1]%10,res[-1]//10\n",
    "            j-=1\n",
    "        if carry:\n",
    "            res.append(1)\n",
    "        return res[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        #小学加法，从低到高依次计算\n",
    "        k = list(map(int,str(k)))\n",
    "        L1,L2 = len(num)-1,len(k)-1\n",
    "        ans = []\n",
    "        #进位\n",
    "        carry = 0\n",
    "        while L1>=0 and L2>=0:\n",
    "            add = num[L1]+k[L2]+carry\n",
    "            ans.append(add%10)\n",
    "            carry = add//10\n",
    "            L1 -= 1\n",
    "            L2 -= 1\n",
    "        while L1>=0:\n",
    "            add = num[L1]+carry\n",
    "            ans.append(add%10)\n",
    "            carry = add//10\n",
    "            L1 -= 1\n",
    "        while L2>=0:\n",
    "            add = k[L2]+carry\n",
    "            ans.append(add%10)\n",
    "            carry = add//10\n",
    "            L2 -= 1\n",
    "        if carry == 1:\n",
    "            ans.append(carry)\n",
    "        return ans[::-1]\n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        num.reverse()\n",
    "        n=0\n",
    "        for i in range(len(num)):\n",
    "            n+=num[i]*10**i\n",
    "\n",
    "\n",
    "        import sys\n",
    "        sys.set_int_max_str_digits(40000)\n",
    "\n",
    "        \n",
    "        result = list(str(n+k))\n",
    "\n",
    "        rr = []\n",
    "        for i in range(len(result)):\n",
    "            rr.append(int(result[i]))\n",
    "\n",
    "        return rr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        k = list(map(int,str(k)))\n",
    "        \n",
    "        res = []\n",
    "        i,j = len(num)-1,len(k)-1\n",
    "        carry = 0\n",
    "\n",
    "        while i >= 0 and j >= 0:\n",
    "            res.append(num[i] + k[j] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            i -= 1\n",
    "            j -= 1\n",
    "        while i >= 0:\n",
    "            res.append(num[i] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            i -= 1\n",
    "        while j >= 0:\n",
    "            res.append(k[j] + carry)\n",
    "            res[-1],carry = res[-1] % 10, res[-1] // 10\n",
    "            j -= 1\n",
    "\n",
    "        if carry:\n",
    "            res.append(1)\n",
    "\n",
    "        return res[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        kList = [eval(x) for x in str(k)]\n",
    "        # print(\"kList: \", kList)\n",
    "\n",
    "        num1 = num[::-1]\n",
    "        kList1 = kList[::-1]\n",
    "\n",
    "        if len(num1) > len(kList1):\n",
    "            num1, kList1 = kList1, num1 \n",
    "\n",
    "        len1 = len(num1)\n",
    "        len2 = len(kList1)\n",
    "        add = 0\n",
    "        i = 0\n",
    "        res = []\n",
    "\n",
    "        while i < len1 or i < len2 or add != 0:\n",
    "            if i< len1:\n",
    "                v = num1[i] + kList1[i] + add\n",
    "            elif i < len2:\n",
    "                v = kList1[i] + add\n",
    "            else:\n",
    "                v = add \n",
    "\n",
    "            if v > 9:\n",
    "                add = 1\n",
    "                v1 = v % 10\n",
    "            else:\n",
    "                add = 0\n",
    "                v1 = v\n",
    "            \n",
    "            res.append(v1)\n",
    "            i += 1\n",
    "        \n",
    "\n",
    "        return res[::-1]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        import sys\n",
    "        sys.set_int_max_str_digits(0)  \n",
    "        return [ int(_) for _ in str(int(\"\".join(str(_) for _ in num))+k) ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        res = []\n",
    "        k1 = [int(x) for x in str(k)] \n",
    "        n1,n2,add = len(num)-1, len(k1)-1, 0\n",
    "        while n1 >= 0 or n2 >= 0:\n",
    "            print(n1,n2)\n",
    "            x = num[n1] if n1 >=0 else 0\n",
    "            y = k1[n2] if n2 >=0 else 0\n",
    "            sum = x+y+add\n",
    "            res.append(sum % 10)\n",
    "            add = sum // 10\n",
    "            n1 = n1 - 1\n",
    "            n2 = n2-1\n",
    "        if add != 0: res.append(add)\n",
    "        return res[::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        s=0\n",
    "        anas=[]\n",
    "        num=num[::-1]\n",
    "        m=0\n",
    "        while(m<len(num) and k!=0):\n",
    "            print(m,len(num))\n",
    "            h=(num[m]+k%10+s)%10\n",
    "            s=(num[m]+k%10+s)//10\n",
    "            anas.append(h)\n",
    "            m=m+1\n",
    "            k=k//10\n",
    "        if m!=len(num):\n",
    "            while(m<len(num)):\n",
    "                h=(num[m]+s)%10\n",
    "                s=(num[m]+s)//10\n",
    "                anas.append(h)\n",
    "                m=m+1\n",
    "        if k!=0:\n",
    "            while(k!=0):\n",
    "                h=(k%10+s)%10\n",
    "                s=(k%10+s)//10\n",
    "                anas.append(h)\n",
    "                k=k//10\n",
    "        if s==1:\n",
    "            anas.append(1)\n",
    "        return anas[::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "sys.set_int_max_str_digits(100000) \n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        result = int(''.join(map(str, num))) + k\n",
    "        # Convert the result back to a list of digits and return it.\n",
    "        return list(map(int, str(result)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(10001)\n",
    "        return list(map(int,str(k+int(''.join(map(str,num))))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(500000)\n",
    "\n",
    "        return list(map(int,str(int(\"\".join(map(str,num))) + k)))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        # str_num = \"\".join([str(n) for n in num])\n",
    "        # sum_num = int(str_num) + k\n",
    "        # list_num = list(str(sum_num))\n",
    "        # return [int(l) for l in list_num]\n",
    "        # ↑ 上述方法在使用 num 长度大于某个值的情况下就会导致溢出错误\n",
    "        # ValueError: Exceeds the limit (4300) for integer string conversion: value has 10000 digits; use sys.set_int_max_str_digits() to increase the limit\n",
    "\n",
    "        num_k = list(str(k))\n",
    "        num_k = [int(i) for i in num_k]\n",
    "\n",
    "        max_len = max(len(num), len(num_k))\n",
    "        num = [0] * (max_len - len(num)) + num\n",
    "        num_k = [0] * (max_len - len(num_k)) + num_k\n",
    "\n",
    "        res = []\n",
    "        jinwei = 0\n",
    "        while num and num_k:\n",
    "            n1 = num.pop(-1)\n",
    "            n2 = num_k.pop(-1)\n",
    "            \n",
    "            yushu = (n1 + n2 + jinwei) % 10\n",
    "            res.insert(0, yushu)\n",
    "            jinwei = (n1 + n2 + jinwei) // 10\n",
    "        \n",
    "        if jinwei > 0:\n",
    "            res.insert(0, jinwei)\n",
    "        \n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(20000)\n",
    "        str1=\"\".join(map(str,num))\n",
    "        a=int(str1)+k\n",
    "        a=list(map(int,str(a)))\n",
    "        return a\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(20000)\n",
    "        return list(map(int, str(int(''.join(map(str, num))) + k)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(15000)  # 增加限制为15000位\n",
    "\n",
    "        # 列表合并整数\n",
    "        # s=''\n",
    "        # for i in num:\n",
    "        #     s=s+str(i)  # 字符串\n",
    "        # s=int(s)   # 有限制\n",
    "        num = [str(i) for i in num]\n",
    "        s=int(''.join(num))   # 有限制\n",
    "        res=s+k\n",
    "        # 整数转换为列表\n",
    "        # 一\n",
    "        # res=str(res)\n",
    "        # new_list=[]\n",
    "        # for i in res:\n",
    "        #     new_list.append(int(i))\n",
    "        # 二\n",
    "        # new_list=[int(x) for x in str(res)] \n",
    "        # 三\n",
    "        new_list=[]\n",
    "        while res:\n",
    "            new_list.append(res%10)\n",
    "            res=res//10\n",
    "        return new_list[::-1]\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        import sys\n",
    "        sys.set_int_max_str_digits(20000)\n",
    "        num = int(\"\".join(map(str, num))) + k\n",
    "        return [int(d) for d in str(num)]\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    sys.set_int_max_str_digits(1000000)\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        new_num = int(''.join(map(lambda x: str(x), num)))\n",
    "        str1 = str(new_num+k)\n",
    "        return [int(_) for _ in str1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(15000)  # 增加限制为15000位\n",
    "\n",
    "        # 列表合并整数\n",
    "        # s=''\n",
    "        # for i in num:\n",
    "        #     s=s+str(i)  # 字符串\n",
    "        # s=int(s)   # 有限制\n",
    "        num = [str(i) for i in num]\n",
    "        s=int(''.join(num))   # 有限制\n",
    "        res=s+k\n",
    "        res=str(res)\n",
    "        new_list=[]\n",
    "        for i in res:\n",
    "            new_list.append(int(i))\n",
    "        return new_list\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(100000) \n",
    "        ans = list(str(int(''.join(list(map(lambda x: str(x), num)))) + k))\n",
    "        return list(map(lambda x: int(x), ans))\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addToArrayForm(self, num: List[int], k: int) -> List[int]:\n",
    "        sys.set_int_max_str_digits(100000) \n",
    "        ans = list(str(int(''.join(list(map(lambda x: str(x), num)))) + k))\n",
    "        return list(map(lambda x: int(x), ans))\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        pre = None\n",
    "        cur = head\n",
    "        while cur:\n",
    "            nxt = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = nxt\n",
    "        return pre\n",
    "\n",
    "    def addTwo(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        cur = dummy = ListNode()  # 哨兵节点\n",
    "        carry = 0  # 进位\n",
    "        while l1 or l2 or carry:  # 有一个不是空节点，或者还有进位，就继续迭代\n",
    "            if l1: carry += l1.val  # 节点值和进位加在一起\n",
    "            if l2: carry += l2.val  # 节点值和进位加在一起\n",
    "            cur.next = ListNode(carry % 10)  # 每个节点保存一个数位\n",
    "            carry //= 10  # 新的进位\n",
    "            cur = cur.next  # 下一个节点\n",
    "            if l1: l1 = l1.next  # 下一个节点\n",
    "            if l2: l2 = l2.next  # 下一个节点\n",
    "        return dummy.next  # 哨兵节点的下一个节点就是头节点\n",
    "\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self.reverseList(l1)\n",
    "        l2 = self.reverseList(l2)  # l1 和 l2 反转后，就变成【2. 两数相加】了\n",
    "        l3 = self.addTwo(l1, l2)\n",
    "        return self.reverseList(l3)  # 计算完毕后再反转\n",
    "\n",
    "                \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def reverse_list(head):\n",
    "            if head.next==None:\n",
    "                return head\n",
    "            current=head\n",
    "            parent= None\n",
    "            while(current is not None):\n",
    "                temp=current.next\n",
    "                current.next=parent\n",
    "                parent=current\n",
    "                current=temp\n",
    "            return parent\n",
    "\n",
    "        l1_rev=reverse_list(l1)\n",
    "        l2_rev=reverse_list(l2)\n",
    "        carry=0\n",
    "        res_head=ListNode()\n",
    "        res_current=res_head\n",
    "        l1_current=l1_rev\n",
    "        l2_current=l2_rev\n",
    "\n",
    "        while l1_current is not None or l2_current is not None or carry!=0:\n",
    "            if l1_current is not None:\n",
    "                l1_num=l1_current.val\n",
    "                l1_current=l1_current.next\n",
    "            else:\n",
    "                l1_num=0\n",
    "            if l2_current is not None:\n",
    "                l2_num=l2_current.val\n",
    "                l2_current=l2_current.next\n",
    "            else:\n",
    "                l2_num=0                \n",
    "            res_current.val=(l1_num+l2_num+carry)%10\n",
    "            carry= int((l1_num+l2_num+carry)/10)\n",
    "            if l1_current is not None or l2_current is not None or carry!=0:\n",
    "                res_current.next=ListNode()\n",
    "                res_current=res_current.next\n",
    "            else:\n",
    "                tail=res_current\n",
    "        res_head = reverse_list(res_head)\n",
    "        return res_head"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "\n",
    "# 使用栈时间复杂度，空间复杂度都为0(m+n)\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack1 = []\n",
    "        stack2 = []\n",
    "        while l1:\n",
    "            stack1.append(l1)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            stack2.append(l2)\n",
    "            l2 = l2.next\n",
    "        \n",
    "        carry = 0 \n",
    "        sum = 0\n",
    "        node = None\n",
    "        pre = None\n",
    "        while stack1 or stack2:\n",
    "            if not stack1:\n",
    "                val1 = 0\n",
    "                node = stack2[-1]\n",
    "            else:\n",
    "                node = stack1.pop()\n",
    "                val1 = node.val\n",
    "\n",
    "            if not stack2:\n",
    "                val2 = 0\n",
    "            else:\n",
    "                val2 = stack2.pop().val\n",
    "\n",
    "            sum = (val1 + val2 + carry)%10\n",
    "            carry = (val1 + val2 + carry)//10\n",
    "\n",
    "            node.val = sum\n",
    "            node.next = pre\n",
    "            pre = node\n",
    "        \n",
    "        if carry!=0:\n",
    "            node = ListNode()\n",
    "            node.val = 1\n",
    "            node.next = pre\n",
    "\n",
    "        return node\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        listA = list()\n",
    "        listB = list()\n",
    "        while l1:\n",
    "            listA.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            listB.append(l2.val)\n",
    "            l2 = l2.next\n",
    "\n",
    "        ans_list = list()\n",
    "        sum_up = 0\n",
    "        while listA or listB:\n",
    "            a = 0 if not listA else listA.pop()\n",
    "            b = 0 if not listB else listB.pop()\n",
    "            ans_list.append((a+b+sum_up) % 10)       # sum_up放在里面，防止连续进位\n",
    "            sum_up = (a+b+sum_up) // 10\n",
    "        \n",
    "\n",
    "        if sum_up:\n",
    "            ans_list.append(1)           # 5+5的场景\n",
    "\n",
    "        \n",
    "        ans = ListNode(ans_list.pop())\n",
    "        prev = ans\n",
    "        while ans_list:\n",
    "            prev.next = ListNode(ans_list.pop())   # 需要创建下个节点，创建当前节点的话会多一个next\n",
    "            prev = prev.next\n",
    "\n",
    "        return ans\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1,s2=[],[]\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1=l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2=l2.next\n",
    "        ans=None\n",
    "        carry=0    \n",
    "        while s1 or s2 or carry!=0:\n",
    "            a=0 if not s1 else s1.pop()\n",
    "            b=0 if not s2 else s2.pop() \n",
    "            cur=a+b+carry\n",
    "            carry=cur//10\n",
    "            cur %=10\n",
    "            curnode=ListNode(cur)\n",
    "            curnode.next=ans\n",
    "            ans=curnode\n",
    "        return ans    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def reverse(head):\n",
    "            tail = None\n",
    "            cur = head\n",
    "            while cur is not None:\n",
    "                next = cur.next\n",
    "                cur.next = tail\n",
    "                tail = cur\n",
    "                cur = next\n",
    "            return tail\n",
    "        l1 = reverse(l1)\n",
    "        l2 = reverse(l2)\n",
    "        carry = 0\n",
    "        ans = ListNode(0)\n",
    "        cur = ans\n",
    "        while l1 or l2 or carry != 0:\n",
    "            l1v = l1.val if l1 is not None else 0\n",
    "            l2v = l2.val if l2 is not None else 0\n",
    "            s = l1v + l2v + carry\n",
    "            cur.next = ListNode(s % 10)\n",
    "            cur = cur.next\n",
    "            carry = s // 10\n",
    "            if l1 is not None:\n",
    "                l1 = l1.next \n",
    "            if l2 is not None:\n",
    "                l2 = l2.next\n",
    "        return reverse(ans.next)            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1, s2 = [], []\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        dummy = ListNode()\n",
    "        carry = 0\n",
    "        while s1 or s2 or carry:\n",
    "            s = (0 if not s1 else s1.pop()) + (0 if not s2 else s2.pop()) + carry\n",
    "            carry, val = divmod(s, 10)\n",
    "            dummy.next = ListNode(val, dummy.next)\n",
    "\n",
    "        return dummy.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def reserve(root):\n",
    "            pre = None\n",
    "            while root:\n",
    "                tmp = root.next\n",
    "                root.next = pre\n",
    "                pre = root\n",
    "                root = tmp\n",
    "            return pre\n",
    "        l1 = reserve(l1)\n",
    "        l2 = reserve(l2)\n",
    "        s = ListNode(0)\n",
    "        r = s\n",
    "        flag = 0\n",
    "        while l1 and l2:\n",
    "            cur = l1.val + l2.val + flag\n",
    "            s.next = ListNode(cur%10)\n",
    "            flag = cur//10\n",
    "            s = s.next\n",
    "            l1 = l1.next\n",
    "            l2 = l2.next\n",
    "        while l1:\n",
    "            cur = l1.val + flag\n",
    "            s.next = ListNode(cur%10)\n",
    "            flag = cur//10\n",
    "            s = s.next\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            cur = l2.val + flag\n",
    "            s.next = ListNode(cur%10)\n",
    "            flag = cur//10\n",
    "            s = s.next\n",
    "            l2 = l2.next\n",
    "        if flag > 0:\n",
    "            s.next = ListNode(flag)\n",
    "        return reserve(r.next)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def calc(node):\n",
    "            ans = 0\n",
    "            while node:\n",
    "                ans = ans*10\n",
    "                ans += node.val\n",
    "                node = node.next\n",
    "            return ans\n",
    "        n1 = calc(l1)\n",
    "        n2 = calc(l2)\n",
    "        he = n1+n2\n",
    "        strhe = str(he)\n",
    "        dummy = ListNode(-1)\n",
    "        p = dummy\n",
    "        for i in range(len(strhe)):\n",
    "            node = ListNode(int(strhe[i]))\n",
    "            p.next = node\n",
    "            p = p.next\n",
    "        return dummy.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack_1 = []\n",
    "        stack_2 = []\n",
    "        while l1:\n",
    "            stack_1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        \n",
    "        while l2:\n",
    "            stack_2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "\n",
    "        following = None\n",
    "        carry = 0\n",
    "        while stack_1 or stack_2 or carry != 0:\n",
    "            num_1 = stack_1.pop() if stack_1 else 0\n",
    "            num_2 = stack_2.pop() if stack_2 else 0\n",
    "            temp = (carry + num_1 + num_2) % 10\n",
    "            carry = (carry + num_1 + num_2) // 10\n",
    "            curr = ListNode(temp)\n",
    "            curr.next = following\n",
    "            following = curr\n",
    "\n",
    "        return following"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack_1 = []\n",
    "        stack_2 = []\n",
    "        while l1:\n",
    "            stack_1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        \n",
    "        while l2:\n",
    "            stack_2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "\n",
    "        following = None\n",
    "        carry = 0\n",
    "        while stack_1 or stack_2 or carry != 0:\n",
    "            num_1 = stack_1.pop() if stack_1 else 0\n",
    "            num_2 = stack_2.pop() if stack_2 else 0\n",
    "            temp = (carry + num_1 + num_2) % 10\n",
    "            carry = (carry + num_1 + num_2) // 10\n",
    "            curr = ListNode(temp)\n",
    "            curr.next = following\n",
    "            following = curr\n",
    "        \n",
    "        # if carry:\n",
    "        #     curr = ListNode(carry)\n",
    "        #     curr.next = following\n",
    "        #     following = curr\n",
    "\n",
    "        return following"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "\n",
    "class Solution:\n",
    "  def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:\n",
    "    cur, pre = head, None\n",
    "    while cur:\n",
    "      temp = cur.next\n",
    "      cur.next = pre\n",
    "      pre = cur\n",
    "      cur = temp\n",
    "    return pre\n",
    "  def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "    l1, l2 = self.reverseList(l1), self.reverseList(l2)\n",
    "    cur = dummy = ListNode()\n",
    "    carry = 0\n",
    "\n",
    "    while l1 or l2 or carry:\n",
    "      carry += (l1.val if l1 else 0) + (l2.val if l2 else 0) \n",
    "      cur.next = ListNode(carry % 10)\n",
    "      carry //= 10\n",
    "      cur = cur.next\n",
    "      \n",
    "      if l1: l1 = l1.next\n",
    "      if l2: l2 = l2.next\n",
    "\n",
    "    return self.reverseList(dummy.next)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "from typing import Optional\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def get_n(l):\n",
    "            n = 0\n",
    "            while l is not None:\n",
    "                n *= 10\n",
    "                n += l.val\n",
    "                l = l.next\n",
    "            return n\n",
    "        n1 = get_n(l1)\n",
    "        n2 = get_n(l2)\n",
    "\n",
    "        head = ListNode()\n",
    "        cur = head\n",
    "        n = n1 + n2\n",
    "        val_list = [int(c) for c in str(n)]\n",
    "        for v in val_list:\n",
    "            cur.next = ListNode(val = v)\n",
    "            cur = cur.next\n",
    "\n",
    "        return head.next\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "def rever(l: Optional[ListNode]) -> Optional[ListNode]:\n",
    "    head = ListNode(next=l)\n",
    "    cur = l.next\n",
    "    while cur:\n",
    "        l.next = cur.next\n",
    "        cur.next = head.next\n",
    "        head.next = cur\n",
    "        cur = l.next\n",
    "    return head.next\n",
    "\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        \n",
    "        #先全部逆置\n",
    "        #然后从低位到高位进行加和进位\n",
    "        #7 2 4 3\n",
    "        #  5 6 4\n",
    "        #=>\n",
    "        #3 4 2 7\n",
    "        #4 6 5\n",
    "        more = 0\n",
    "        l1 = rever(l=l1)\n",
    "        l2 = rever(l=l2)\n",
    "        res_head = ListNode(next=None)\n",
    "        while l1 and l2:\n",
    "            #head insert\n",
    "            sum = l1.val + l2.val + more\n",
    "            node = ListNode(val=sum % 10, next=res_head.next)\n",
    "            res_head.next = node\n",
    "            if sum >= 10:\n",
    "                more = 1\n",
    "            else:\n",
    "                more = 0\n",
    "            l1 = l1.next\n",
    "            l2 = l2.next\n",
    "        if l1:\n",
    "            while l1:\n",
    "                sum = l1.val + more\n",
    "                node = ListNode(val=sum % 10, next=res_head.next)\n",
    "                res_head.next = node\n",
    "                if sum >= 10:\n",
    "                    more = 1\n",
    "                else:\n",
    "                    more = 0\n",
    "                l1 = l1.next\n",
    "            if more == 1:\n",
    "                node = ListNode(val=1, next=res_head.next)\n",
    "                res_head.next = node\n",
    "        elif l2:\n",
    "            while l2:\n",
    "                sum = l2.val + more\n",
    "                node = ListNode(val=sum % 10, next=res_head.next)\n",
    "                res_head.next = node\n",
    "                if sum >= 10:\n",
    "                    more = 1\n",
    "                else:\n",
    "                    more = 0\n",
    "                l2 = l2.next\n",
    "            if more == 1:\n",
    "                node = ListNode(val=1, next=res_head.next)\n",
    "                res_head.next = node\n",
    "        else:\n",
    "            if more == 1:\n",
    "                node = ListNode(val=1, next=res_head.next)\n",
    "                res_head.next = node\n",
    "        return res_head.next\n",
    "        #或者把两个数提出来相加得到结果\n",
    "        #然后转化为链表\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1, n1 = self.reverse(l1)\n",
    "        l2, n2 = self.reverse(l2)\n",
    "        if n1 < n2:\n",
    "            l1, l2 = l2, l1\n",
    "        r = 0\n",
    "        head = l1\n",
    "        while l1:\n",
    "            l2_val = l2.val if l2 else 0\n",
    "            # print(l1.val, /l2_val, r)\n",
    "            l1.val = l1.val + l2_val + r\n",
    "            r = l1.val // 10\n",
    "            l1.val = l1.val % 10\n",
    "            pre = l1\n",
    "            l1 = l1.next\n",
    "            l2 = l2.next if l2 else None\n",
    "        if r > 0:\n",
    "            node = ListNode(r)\n",
    "            pre.next = node\n",
    "        # return head\n",
    "        res, _ = self.reverse(head)\n",
    "        return res\n",
    "\n",
    "\n",
    "\n",
    "    def reverse(self, l):\n",
    "        pre, curr = None, l\n",
    "        n = 0\n",
    "        while curr:\n",
    "            n += 1\n",
    "            nxt = curr.next\n",
    "            curr.next = pre\n",
    "            pre, curr = curr, nxt\n",
    "        return pre, n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def reverseList(self,head:Optional[ListNode])->Optional[ListNode]:\n",
    "        pre = None\n",
    "        cur = head\n",
    "        while cur:\n",
    "            nxt = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = nxt\n",
    "        return pre\n",
    "    def addTwo(self,l1:Optional[ListNode],l2:Optional[ListNode])->Optional[ListNode]:\n",
    "        cur = dummy = ListNode()\n",
    "        carry = 0\n",
    "        while l1 or l2 or carry:\n",
    "            carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "            cur.next = ListNode(carry%10)\n",
    "            carry //= 10\n",
    "            cur = cur.next\n",
    "            if l1:l1 = l1.next\n",
    "            if l2:l2 = l2.next\n",
    "        return dummy.next\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self.reverseList(l1)\n",
    "        l2 = self.reverseList(l2)\n",
    "        l3 = self.addTwo(l1,l2)\n",
    "        return self.reverseList(l3)\n",
    "        \n",
    "            \n",
    "\n",
    "\n",
    "        \n",
    "                \n",
    "        \n",
    "        \n",
    "\n",
    "        \n",
    " \n",
    "\n",
    "\n",
    "        \n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def reverseln(self,head):\n",
    "        cur,pre = head,None\n",
    "        while cur:\n",
    "            tmp = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = tmp\n",
    "        return pre\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1_n = self.reverseln(l1)\n",
    "        l2_n = self.reverseln(l2)\n",
    "\n",
    "        p1,p2 = l1_n,l2_n\n",
    "        dummy = ListNode()\n",
    "        p = dummy\n",
    "        carry = 0\n",
    "        while p1 or p2 or carry:\n",
    "            val = carry\n",
    "            if p1:\n",
    "                val += p1.val\n",
    "                p1 = p1.next\n",
    "            if p2:\n",
    "                val += p2.val\n",
    "                p2 = p2.next\n",
    "            \n",
    "            carry,val = divmod(val,10)\n",
    "\n",
    "            p.next = ListNode(val)\n",
    "            p = p.next\n",
    "        result_head = dummy.next\n",
    "        return self.reverseln(dummy.next)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def fun(l):\n",
    "            p = None\n",
    "            while l:\n",
    "                l.next, p, l = p, l, l.next\n",
    "            return p\n",
    "\n",
    "        def add(l1, l2):\n",
    "\n",
    "            if not l1: return l2\n",
    "            if not l2: return l1\n",
    "\n",
    "            l1.val += l2.val\n",
    "            if l1.val >= 10:\n",
    "                l1.next = add(ListNode(1), l1.next)\n",
    "                l1.val %= 10\n",
    "\n",
    "            l1.next = add(l1.next, l2.next)\n",
    "            return l1\n",
    "        \n",
    "        l1, l2 = fun(l1), fun(l2) \n",
    "\n",
    "        return fun(add(l1, l2))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def lreverse(head):\n",
    "            new = None\n",
    "            cur = head\n",
    "            while cur:\n",
    "                node = ListNode(cur.val)\n",
    "                node.next = new\n",
    "                new = node\n",
    "                cur = cur.next\n",
    "            return new\n",
    "        l1 = lreverse(l1)\n",
    "        l2 = lreverse(l2)\n",
    "        ans = None\n",
    "        flag = 0\n",
    "        while l1.val >= 0 or l2.val >= 0 or flag == 1:\n",
    "            t1 = l1.val if l1.val > 0 else 0\n",
    "            t2 = l2.val if l2.val > 0 else 0\n",
    "            if t1 + t2 + flag > 9:\n",
    "                node = ListNode(t1 + t2 + flag - 10)\n",
    "                flag = 1\n",
    "            else:\n",
    "                node = ListNode(t1 + t2 + flag)\n",
    "                flag = 0\n",
    "            node.next = ans\n",
    "            l1 = l1.next if l1.next else ListNode(-1)\n",
    "            l2 = l2.next if l2.next else ListNode(-1)\n",
    "            ans = node\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        stack1 = self.pushStack(l1)\n",
    "        stack2 = self.pushStack(l2)\n",
    "\n",
    "        dummyHead = ListNode()\n",
    "        head = dummyHead\n",
    "        carry = 0\n",
    "        while stack1 or stack2 or carry:\n",
    "            val = carry\n",
    "            if stack1:\n",
    "                val += stack1.pop()\n",
    "            if stack2:\n",
    "                val += stack2.pop()\n",
    "            carry = val // 10\n",
    "            tmp = head.next\n",
    "            head.next = ListNode(val % 10)\n",
    "            head.next.next = tmp\n",
    "\n",
    "        return dummyHead.next\n",
    "\n",
    "    def pushStack(self, l: ListNode) -> List[int]:\n",
    "        stack = []\n",
    "        while l:\n",
    "            stack.append(l.val)\n",
    "            l = l.next\n",
    "        return stack\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1, s2 = [],[]\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        carry = 0\n",
    "        ans = None\n",
    "        while s1 or s2 or carry:\n",
    "            s = (s1.pop() if s1 else 0) + (s2.pop() if s2 else 0) + carry\n",
    "            carry, value = divmod(s, 10)\n",
    "            cur = ListNode(val = value)\n",
    "            cur.next = ans\n",
    "            ans = cur\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack1 = []\n",
    "        stack2 = []\n",
    "        while l1:\n",
    "            stack1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            stack2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        carry = 0\n",
    "        pre = None\n",
    "        while stack1 or stack2 or carry > 0:\n",
    "            sum = 0\n",
    "            sum += 0 if not stack1 else stack1.pop()\n",
    "            sum += 0 if not stack2 else stack2.pop()\n",
    "            sum += carry\n",
    "            carry = sum // 10\n",
    "            cur = ListNode(sum % 10)\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "        return pre\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 第1步：将2个链表变成2个字符串\n",
    "        str1, str2 = '', ''\n",
    "        p1, p2 = l1, l2\n",
    "        while p1:\n",
    "            str1 += str(p1.val)\n",
    "            p1 = p1.next\n",
    "        while p2:\n",
    "            str2 += str(p2.val)\n",
    "            p2 = p2.next\n",
    "        \n",
    "        # 第2步：将2个字符串变成数字，相加\n",
    "        str3 = str(eval(''.join([str1, '+', str2])))\n",
    "        # str3 = str(int(str1) + int(str2))\n",
    "        \n",
    "        # 第3步：将结果变成链表\n",
    "        pre = None\n",
    "        for i in range(len(str3) - 1, -1, -1):\n",
    "            curnode = ListNode(int(str3[i]))\n",
    "            curnode.next = pre\n",
    "            pre = curnode\n",
    "        return pre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack1, stack2 = [], []\n",
    "        while l1:\n",
    "            stack1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            stack2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        newListNode = None\n",
    "        carry = 0\n",
    "        while stack1 or stack2 or carry != 0:\n",
    "            a = 0 if not stack1 else stack1.pop()\n",
    "            b = 0 if not stack2 else stack2.pop()\n",
    "            sum = a + b + carry\n",
    "            carry = sum // 10\n",
    "            sum %= 10\n",
    "            curNode = ListNode(sum, newListNode)\n",
    "            newListNode = curNode\n",
    "        return newListNode"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        '''翻转链表 -> 计算结果 -> 翻转链表\n",
    "        '''\n",
    "\n",
    "        def reverse_list(head):\n",
    "            '''翻转链表\n",
    "            '''\n",
    "            if head is None or head.next is None:\n",
    "                # 无节点或只有一个节点，直接返回\n",
    "                return head\n",
    "\n",
    "            slow = head; fast = head.next\n",
    "            while(fast is not None):\n",
    "                tmp = fast.next\n",
    "                fast.next = slow\n",
    "                if slow is head:\n",
    "                    slow.next = None\n",
    "                slow = fast\n",
    "                fast = tmp\n",
    "            \n",
    "            return slow\n",
    "\n",
    "        l1 = reverse_list(l1)\n",
    "        l2 = reverse_list(l2)\n",
    "\n",
    "        dummy_head = ListNode()\n",
    "        curr_out = dummy_head\n",
    "        curr1 = l1\n",
    "        curr2 = l2\n",
    "        tmp = 0\n",
    "        while(curr1 is not None or curr2 is not None):\n",
    "            val = 0\n",
    "            if curr1 is not None:\n",
    "                val += curr1.val\n",
    "                curr1 = curr1.next\n",
    "\n",
    "            if curr2 is not None:\n",
    "                val += curr2.val\n",
    "                curr2 = curr2.next\n",
    "\n",
    "            val += tmp\n",
    "            curr_out.next = ListNode(val % 10)\n",
    "            curr_out = curr_out.next\n",
    "            tmp = val // 10\n",
    "\n",
    "        if tmp:\n",
    "            curr_out.next = ListNode(tmp)\n",
    "\n",
    "        rst = dummy_head.next\n",
    "        rst = reverse_list(rst)\n",
    "        return rst"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        rl1, rl2 = self.reverse(l1), self.reverse(l2)\n",
    "        temp = 0\n",
    "        pre = cur = ListNode()\n",
    "        while rl1 or rl2 or temp:\n",
    "            temp += (rl1.val if rl1 else 0) + (rl2.val if rl2 else 0)\n",
    "            cur.next = ListNode(temp%10)\n",
    "            temp //= 10\n",
    "            cur = cur.next\n",
    "            if rl1: rl1 = rl1.next\n",
    "            if rl2: rl2 = rl2.next\n",
    "\n",
    "        return self.reverse(pre.next)\n",
    "    def reverse(self, head):\n",
    "        cur, pre = head, None\n",
    "        while cur:\n",
    "            temp = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = temp\n",
    "        \n",
    "        return pre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self.reverseList(l1)\n",
    "        l2 = self.reverseList(l2)\n",
    "        p0 = new = ListNode(None)\n",
    "        t = 0\n",
    "        while l1 and l2:\n",
    "            a = t + l1.val + l2.val\n",
    "            t, a = divmod(a, 10)\n",
    "            new.next = ListNode(a)\n",
    "            new = new.next\n",
    "            l2 = l2.next\n",
    "            l1 = l1.next\n",
    "        while l1:\n",
    "            a = t + l1.val\n",
    "            t, a = divmod(a, 10)\n",
    "            new.next = ListNode(a)\n",
    "            new = new.next\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            a = t + l2.val\n",
    "            t, a = divmod(a, 10)\n",
    "            new.next = ListNode(a)\n",
    "            new = new.next\n",
    "            l2 = l2.next\n",
    "        if t!=0:\n",
    "            new.next = ListNode(t)\n",
    "        return self.reverseList(p0.next)\n",
    "\n",
    "    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        pre = None\n",
    "        cur = head\n",
    "        while cur:\n",
    "            nxt = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = nxt\n",
    "        return pre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        s1, s2 = [], []\n",
    "        dummy = ListNode()\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        carry = 0\n",
    "\n",
    "        while s1 or s2 or carry:\n",
    "            result_1 = 0 if not s1 else s1.pop()\n",
    "            result_2 = 0 if not s2 else s2.pop() \n",
    "            carry,val = divmod(result_1+result_2+carry, 10)\n",
    "            #carry = (result_1 + result_2 + carry) // 10\n",
    "            #val = (result_1 + result_2 + carry) % 10\n",
    "            dummy.next = ListNode(val, dummy.next)\n",
    "        return dummy.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        num1,num2=0,0\n",
    "        while l1!=None:\n",
    "            num1=num1*10+l1.val\n",
    "            l1=l1.next\n",
    "        while l2!=None:\n",
    "            num2=num2*10+l2.val\n",
    "            l2=l2.next\n",
    "        ret=ListNode()\n",
    "        ret_num=str(num1+num2)\n",
    "        last=ret\n",
    "        for i in ret_num:\n",
    "            q=ListNode(val=int(i))\n",
    "            last.next=q\n",
    "            last=q\n",
    "        return ret.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack1 = []\n",
    "        stack2 = []\n",
    "        while l1:\n",
    "            stack1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            stack2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        nex = None\n",
    "        s = 0\n",
    "        while stack1 or stack2 or s:\n",
    "            n1 = stack1.pop() if stack1 else 0\n",
    "            n2 = stack2.pop() if stack2 else 0\n",
    "            curvalue = n1 + n2 + s\n",
    "            s = curvalue // 10\n",
    "            curvalue %= 10\n",
    "            node = ListNode(val=curvalue, next=nex)\n",
    "            nex = node\n",
    "        return nex"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        p1 = ListNode(0)\n",
    "        p2 = ListNode(0)\n",
    "        while (l1):\n",
    "            tmp = l1.next\n",
    "            l1.next = p1.next\n",
    "            p1.next = l1\n",
    "            l1 = tmp\n",
    "        while(l2):\n",
    "            tmp = l2.next\n",
    "            l2.next = p2.next\n",
    "            p2.next = l2\n",
    "            l2 = tmp\n",
    "        sum1 = ListNode(0)\n",
    "        cur = sum1\n",
    "        cur1 = p1.next\n",
    "        cur2 = p2.next\n",
    "        flag = 0\n",
    "        while(cur1 and cur2):\n",
    "            sum_ = cur1.val + cur2.val + flag\n",
    "            remainder = sum_ % 10\n",
    "            flag = sum_ // 10\n",
    "            cur.next = ListNode(remainder)\n",
    "            cur = cur.next\n",
    "            cur1 = cur1.next\n",
    "            cur2 = cur2.next\n",
    "        while(cur1):\n",
    "            sum_ = cur1.val + flag\n",
    "            remainder = sum_ % 10\n",
    "            flag = sum_ // 10\n",
    "            cur.next = ListNode(remainder)\n",
    "            cur = cur.next\n",
    "            cur1 = cur1.next\n",
    "        while(cur2):\n",
    "            sum_ = cur2.val + flag\n",
    "            remainder = sum_ % 10\n",
    "            flag = sum_ // 10\n",
    "            cur.next = ListNode(remainder)\n",
    "            cur = cur.next\n",
    "            cur2 = cur2.next\n",
    "        if flag != 0:\n",
    "            cur.next = ListNode(flag)\n",
    "        cur = sum1.next\n",
    "        sum1.next = None\n",
    "        while(cur):\n",
    "            tmp = cur.next\n",
    "            cur.next = sum1.next\n",
    "            sum1.next = cur\n",
    "            cur = tmp\n",
    "        return sum1.next\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        return self.reverseList(self.addTwo(self.reverseList(l1),self.reverseList(l2)))\n",
    "    def reverseList(self,head):\n",
    "        cur=head\n",
    "        prev=None\n",
    "        while cur:\n",
    "            temp=cur.next\n",
    "            cur.next=prev\n",
    "            prev=cur\n",
    "            cur=temp\n",
    "        return prev\n",
    "    def addTwo(self,l1,l2):\n",
    "        num_0=0\n",
    "        num_10=0\n",
    "        cur=dum=ListNode()\n",
    "        while l1 or l2:\n",
    "            if not l1:\n",
    "                l1=ListNode(0)\n",
    "            if not l2:\n",
    "                l2=ListNode(0)\n",
    "            num_0=(l1.val+l2.val+num_10)%10\n",
    "            num_10=(l1.val+l2.val+num_10)//10\n",
    "            cur.next=ListNode(val=num_0)\n",
    "            cur=cur.next\n",
    "            l1=l1.next\n",
    "            l2=l2.next\n",
    "        if num_10!=0:\n",
    "            cur.next=ListNode(val=1)\n",
    "        return dum.next\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        p1, p2 = l1, l2\n",
    "        s1, s2 = '', ''\n",
    "        while p1:\n",
    "            s1 += str(p1.val)\n",
    "            p1 = p1.next\n",
    "        while p2:\n",
    "            s2 += str(p2.val)\n",
    "            p2 = p2.next\n",
    "        s3 = str(int(s1) + int(s2))\n",
    "        pre = None\n",
    "        for i in range(len(s3) - 1, -1, -1):\n",
    "            curnode = ListNode(int(s3[i]))\n",
    "            curnode.next = pre\n",
    "            pre = curnode\n",
    "        return pre\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1=self.reverse(l1)\n",
    "        l2=self.reverse(l2)\n",
    "        l3=self.addTwo(l1,l2)\n",
    "        return self.reverse(l3)\n",
    "    def reverse(self,head:Optional[ListNode])->Optional[ListNode]:\n",
    "        pre=None\n",
    "        cur=head\n",
    "        while cur:\n",
    "          n=cur.next\n",
    "          cur.next=pre\n",
    "          pre=cur\n",
    "          cur=n\n",
    "        return pre\n",
    "    def addTwo(self,l1:Optional[ListNode],l2:Optional[ListNode])->Optional:\n",
    "        dummy=ListNode(0)\n",
    "        cur=dummy\n",
    "        carry=0\n",
    "        while l1 or l2 or carry:\n",
    "            carry+=(l1.val if l1 else 0)+(l2.val if l2 else 0)\n",
    "            cur.next=ListNode(carry%10)\n",
    "            cur=cur.next\n",
    "            carry//=10\n",
    "            if l1:l1=l1.next \n",
    "            if l2:l2=l2.next \n",
    "        return dummy.next\n",
    "       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        if l1.val == 0:\n",
    "            return l2\n",
    "        if l2.val == 0:\n",
    "            return l1\n",
    "        stack1 = []\n",
    "        stack2 = []\n",
    "        while l1:\n",
    "            stack1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            stack2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        head = ListNode()\n",
    "        remainder = 0\n",
    "        res = 0\n",
    "        while stack1 and stack2:\n",
    "            num1 = stack1.pop()\n",
    "            num2 = stack2.pop()\n",
    "            res = (num1 + num2 + remainder) % 10\n",
    "            remainder = (num1 + num2 + remainder) // 10\n",
    "            node = ListNode(res)\n",
    "            node.next = head.next\n",
    "            head.next = node\n",
    "        \n",
    "        if len(stack1) != 0:\n",
    "            while stack1:\n",
    "                num = stack1.pop()\n",
    "                res = (num + remainder) % 10\n",
    "                remainder = (num + remainder) // 10\n",
    "                node = ListNode(res)\n",
    "                node.next = head.next\n",
    "                head.next = node\n",
    "        \n",
    "        if len(stack2) != 0:\n",
    "            while stack2:\n",
    "                num = stack2.pop()\n",
    "                res = (num + remainder) % 10\n",
    "                remainder = (num + remainder) // 10\n",
    "                node = ListNode(res)\n",
    "                node.next = head.next\n",
    "                head.next = node\n",
    "        \n",
    "        if len(stack1) == 0 and len(stack2) == 0:\n",
    "            if remainder == 0:\n",
    "                return head.next\n",
    "            else:\n",
    "                node = ListNode(remainder)\n",
    "                node.next = head.next\n",
    "                head.next = node\n",
    "                return head.next\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self.reverse(head=l1)\n",
    "        l2 = self.reverse(head=l2)\n",
    "        cur = dummy = ListNode()\n",
    "        carry = 0\n",
    "        while l1 or l2 or carry:\n",
    "            if l1: carry += l1.val\n",
    "            if l2: carry += l2.val\n",
    "\n",
    "            cur.next = ListNode(carry%10)\n",
    "            carry //= 10\n",
    "            cur = cur.next\n",
    "\n",
    "            if l1: l1 = l1.next\n",
    "            if l2: l2 = l2.next\n",
    "        return self.reverse(dummy.next)\n",
    "            \n",
    "                \n",
    "\n",
    "\n",
    "    def reverse(self,head):\n",
    "        pre = None\n",
    "        cur = head\n",
    "        while cur:\n",
    "            nxt = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = nxt\n",
    "        return pre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stk1, stk2 = [], []\n",
    "        while l1:\n",
    "            stk1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            stk2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        c = 0\n",
    "        a, b = 0, 0\n",
    "        head, f = None, None\n",
    "        while stk1 or stk2:\n",
    "            if stk1:\n",
    "                a = stk1.pop(-1)\n",
    "            if stk2:\n",
    "                b = stk2.pop(-1)\n",
    "            # ans *= 10\n",
    "            f = head\n",
    "            t = ListNode((a+b+c) % 10, f)\n",
    "            head = t\n",
    "            c = (a + b + c) // 10\n",
    "            a = b = 0\n",
    "        if not stk1 and not stk2 and c != 0:\n",
    "            f = head\n",
    "            t = ListNode((a+b+c) % 10, f)\n",
    "            head = t\n",
    "        return head"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        str1, str2 = '', ''\n",
    "        p1, p2 = l1, l2\n",
    "        while p1:\n",
    "            str1 += str(p1.val)\n",
    "            p1 = p1.next\n",
    "        while p2:\n",
    "            str2 += str(p2.val)\n",
    "            p2 = p2.next\n",
    "        str3 = str(eval(''.join([str1, '+', str2])))\n",
    "        pre = None\n",
    "        for i in range(len(str3) - 1, -1, -1):\n",
    "            curnode = ListNode(int(str3[i]))\n",
    "            curnode.next = pre\n",
    "            pre = curnode\n",
    "        return pre"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def addtwo(l1,l2,carry=0):\n",
    "            if not l1 and not l2:\n",
    "                return ListNode(carry) if carry else None\n",
    "            if not l1:\n",
    "                l1,l2 = l2,l1\n",
    "            carry += l1.val + (l2.val if l2 else 0)\n",
    "            l1.val = carry % 10\n",
    "            l1.next = addtwo(l1.next,(l2.next if l2 else None),carry//10)\n",
    "            return l1\n",
    "        def reverse(node):\n",
    "            pre,cur = None,node\n",
    "            while cur:\n",
    "                node_next = cur.next\n",
    "                cur.next = pre\n",
    "                pre = cur\n",
    "                cur = node_next\n",
    "            return pre\n",
    "        l1 = reverse(l1)\n",
    "        l2 = reverse(l2)\n",
    "        l3 = addtwo(l1,l2)\n",
    "        return reverse(l3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        num1 = []\n",
    "        num2 = []\n",
    "        while l1:\n",
    "            num1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            num2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        max_n = max(len(num1), len(num2))\n",
    "        if max_n != len(num1):\n",
    "            num1 = [0 for _ in range(max_n-len(num1))] + num1\n",
    "        if max_n != len(num2):\n",
    "            num2 = [0 for _ in range(max_n-len(num2))] + num2\n",
    "\n",
    "        # core\n",
    "        res = []\n",
    "        jin = 0\n",
    "        for i in range(max_n-1, -1, -1):\n",
    "            value = num1[i] + num2[i] + jin\n",
    "            jin = value // 10\n",
    "            cur = value % 10\n",
    "            res.append(cur)\n",
    "        if jin > 0:\n",
    "            res.append(jin)\n",
    "        res = res[::-1]\n",
    "\n",
    "        dump = ListNode()\n",
    "        head = dump\n",
    "        for i in range(len(res)):\n",
    "            tmp = ListNode()\n",
    "            tmp.val = res[i]\n",
    "            head.next = tmp\n",
    "            head = head.next \n",
    "        return dump.next\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def reverse(l):\n",
    "            pre = None\n",
    "            cur = l\n",
    "            while cur:\n",
    "                tmp = cur.next\n",
    "                cur.next = pre\n",
    "                pre = cur\n",
    "                cur = tmp\n",
    "            return pre\n",
    "        L1, L2 = [], []\n",
    "        while l1:\n",
    "            L1.append(l1)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            L2.append(l2)\n",
    "            l2 = l2.next\n",
    "\n",
    "        up = 0\n",
    "        head = ListNode()\n",
    "        cur = head\n",
    "        while L1 or L2 or up:\n",
    "            val = up\n",
    "            if L1:\n",
    "                val += L1.pop().val\n",
    "            if L2:\n",
    "                val += L2.pop().val\n",
    "            if val>=10:\n",
    "                val-=10\n",
    "                up = 1\n",
    "            else:\n",
    "                up = 0\n",
    "            cur.next = ListNode(val)\n",
    "            cur = cur.next\n",
    "        return reverse(head.next)\n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        num1 = num2 = 0\n",
    "        while l1:\n",
    "            num1 = 10 * num1 + l1.val\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            num2 = 10 * num2 + l2.val\n",
    "            l2 = l2.next\n",
    "        h = ListNode()\n",
    "        cur = h\n",
    "        for c in str(num1 + num2):\n",
    "            cur.next = ListNode(int(c), None)\n",
    "            cur = cur.next\n",
    "        return h.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1_list = []\n",
    "        l2_list = []\n",
    "\n",
    "        while l1:\n",
    "            l1_list.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        \n",
    "        while l2:\n",
    "            l2_list.append(l2.val)\n",
    "            l2 = l2.next\n",
    "\n",
    "        carry = 0\n",
    "        ans = None\n",
    "\n",
    "        while l1_list or l2_list:\n",
    "            if l1_list:\n",
    "                tmp1 = l1_list.pop()\n",
    "            else:\n",
    "                tmp1 = 0\n",
    "            \n",
    "            if l2_list:\n",
    "                tmp2 = l2_list.pop()\n",
    "            else:\n",
    "                tmp2 = 0\n",
    "\n",
    "            value = (tmp1 + tmp2 + carry) % 10\n",
    "            carry = (tmp1 + tmp2 + carry) // 10\n",
    "\n",
    "            if not ans:\n",
    "                ans = ListNode(value)\n",
    "            else:\n",
    "                head = ListNode(value)\n",
    "                head.next = ans\n",
    "                ans = head\n",
    "        \n",
    "        if carry:\n",
    "            head = ListNode(carry)\n",
    "            head.next = ans\n",
    "            ans = head\n",
    "\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        '''\n",
    "        # 方法一：反转列表\n",
    "        def reverse(l):\n",
    "            pre = None\n",
    "            cur = l\n",
    "            while cur:\n",
    "                tmp = cur.next\n",
    "                cur.next = pre\n",
    "                pre = cur\n",
    "                cur = tmp\n",
    "            return pre\n",
    "        \n",
    "        l1 = reverse(l1)\n",
    "        l2 = reverse(l2)\n",
    "        dummy = ListNode(0)\n",
    "        cur = dummy\n",
    "        add = 0\n",
    "        while l1 or l2 or add:\n",
    "            if l1:\n",
    "                val1 = l1.val\n",
    "                l1 = l1.next\n",
    "            else:\n",
    "                val1 = 0\n",
    "            if l2:\n",
    "                val2 = l2.val\n",
    "                l2 = l2.next\n",
    "            else:\n",
    "                val2 = 0\n",
    "            val = val1 + val2 + add\n",
    "            new_node = ListNode(val%10)\n",
    "            add = val // 10\n",
    "            cur.next = new_node\n",
    "            cur = cur.next\n",
    "        return reverse(dummy.next)\n",
    "        '''\n",
    "\n",
    "        # 方法二：栈\n",
    "        stack1 = []\n",
    "        head1 = l1\n",
    "        while head1:\n",
    "            stack1.append(head1.val)\n",
    "            head1 = head1.next\n",
    "        stack2 = []\n",
    "        head2 = l2\n",
    "        while head2:\n",
    "            stack2.append(head2.val)\n",
    "            head2 = head2.next\n",
    "        \n",
    "        add = 0\n",
    "        back = None\n",
    "        while stack1 or stack2 or add:\n",
    "            if stack1:\n",
    "                val1 = stack1.pop()\n",
    "            else:\n",
    "                val1 = 0\n",
    "            if stack2:\n",
    "                val2 = stack2.pop()\n",
    "            else:\n",
    "                val2 = 0\n",
    "            val = val1 + val2 + add\n",
    "            new_node = ListNode(val%10)\n",
    "            add = val // 10\n",
    "            new_node.next = back\n",
    "            back = new_node\n",
    "        return back"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack1, stack2 = [], []\n",
    "        \n",
    "        while l1:\n",
    "            stack1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        \n",
    "        while l2:\n",
    "            stack2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        \n",
    "        carry = 0\n",
    "\n",
    "        res_lst = []\n",
    "        while stack1 or stack2 or carry > 0:\n",
    "            if stack1 and stack2:\n",
    "                temp_val = (stack1.pop() + stack2.pop() + carry) \n",
    "            elif stack1:\n",
    "                temp_val = (stack1.pop() + carry) \n",
    "            elif stack2:\n",
    "                temp_val = (stack2.pop() + carry)\n",
    "            else:\n",
    "                temp_val = carry\n",
    "            \n",
    "            real_val = temp_val % 10\n",
    "            carry = temp_val // 10\n",
    "            res_lst.append(real_val)\n",
    "        \n",
    "        res_lst = res_lst[::-1]\n",
    "        res_node = ListNode(res_lst[0])\n",
    "        temp = res_node\n",
    "        if len(res_lst) == 1:\n",
    "            return res_node\n",
    "        \n",
    "        for val in res_lst[1:]:\n",
    "            temp.next = ListNode(val)\n",
    "            temp = temp.next\n",
    "        \n",
    "        return res_node\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 先反转链表，再用0002.两数相加方法解决\n",
    "        # 反转l1，l2\n",
    "        rl1 = self.reverse(l1)\n",
    "        rl2 = self.reverse(l2)\n",
    "\n",
    "        dummy_head = ListNode(-1)\n",
    "        cur = dummy_head\n",
    "        carry = 0\n",
    "        while rl1 or rl2 or carry:\n",
    "            if rl1:\n",
    "                num1 = rl1.val\n",
    "                rl1 = rl1.next\n",
    "            else:\n",
    "                num1 = 0\n",
    "            if rl2:\n",
    "                num2 = rl2.val\n",
    "                rl2 = rl2.next\n",
    "            else:\n",
    "                num2 = 0\n",
    "            sum = num1 + num2 + carry\n",
    "            carry = sum // 10\n",
    "            inplace_sum = sum % 10\n",
    "            cur.next = ListNode(inplace_sum)\n",
    "            cur = cur.next\n",
    "\n",
    "        # 将结果反转\n",
    "        ans = self.reverse(dummy_head.next)\n",
    "\n",
    "        return ans\n",
    "\n",
    "    # 反转链表函数\n",
    "    def reverse(self, l):\n",
    "        pre = None\n",
    "        cur = l\n",
    "        while cur:\n",
    "            temp = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = temp\n",
    "        return pre\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        s1, s2 = [], []\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        ans = None\n",
    "        carry = 0\n",
    "        while s1 or s2 or carry != 0:\n",
    "            a = 0 if not s1 else s1.pop()\n",
    "            b = 0 if not s2 else s2.pop()\n",
    "            cur = a + b + carry\n",
    "            carry = cur // 10\n",
    "            cur %= 10\n",
    "            curnode = ListNode(cur)\n",
    "            curnode.next = ans\n",
    "            ans = curnode\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1, s2 = [], []\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        \n",
    "        ans = None\n",
    "        carry = 0\n",
    "        while s1 or s2 or carry != 0:\n",
    "            a = 0 if not s1 else s1.pop()\n",
    "            b = 0 if not s2 else s2.pop()\n",
    "            cur = a + b + carry\n",
    "            carry = cur//10\n",
    "            cur %= 10\n",
    "            curnode = ListNode(cur)\n",
    "            curnode.next = ans\n",
    "            ans = curnode\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack1, stack2 = [],[]\n",
    "        # 遍历两个链表，进行入栈操作\n",
    "        while l1 or l2:\n",
    "            if l1:\n",
    "                stack1.append(l1.val)\n",
    "                l1 = l1.next\n",
    "            \n",
    "            if l2:\n",
    "                stack2.append(l2.val)\n",
    "                l2 = l2.next\n",
    "        \n",
    "        # 出栈操作，并按位相加\n",
    "        ans = None\n",
    "        carry = 0\n",
    "        while stack1 and stack2:\n",
    "            n1 = stack1.pop()\n",
    "            n2 = stack2.pop()\n",
    "\n",
    "            r = n1 + n2 + carry\n",
    "\n",
    "            carry = r // 10\n",
    "            val = r % 10\n",
    "            cur_node = ListNode(val)\n",
    "            cur_node.next = ans\n",
    "            ans = cur_node\n",
    "        \n",
    "        while stack1:\n",
    "            n1 = stack1.pop()\n",
    "\n",
    "            r = n1 + carry\n",
    "            carry = r // 10\n",
    "            val = r % 10\n",
    "            cur_node = ListNode(val)\n",
    "            cur_node.next = ans\n",
    "            ans = cur_node\n",
    "        \n",
    "        while stack2:\n",
    "            n1 = stack2.pop()\n",
    "\n",
    "            r = n1 + carry\n",
    "            carry = r // 10\n",
    "            val = r % 10\n",
    "            cur_node = ListNode(val)\n",
    "            cur_node.next = ans\n",
    "            ans = cur_node\n",
    "        \n",
    "        if carry > 0:\n",
    "            cur_node = ListNode(carry)\n",
    "            cur_node.next = ans\n",
    "            ans = cur_node\n",
    "\n",
    "        return ans\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0,    next=None):\n",
    "    \n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1=''\n",
    "        while l1:\n",
    "            s1=s1+str(l1.val)\n",
    "            l1=l1.next\n",
    "        s2 = ''\n",
    "        while l2:\n",
    "            s2 = s2 + str(l2.val)\n",
    "            l2 = l2.next\n",
    "        l=[int(i) for i in list(str(int(s1)+int(s2)))]\n",
    "        hh=ListNode(l.pop(0),None)\n",
    "        h=hh\n",
    "        while l:\n",
    "            nd=ListNode(l.pop(0),None)\n",
    "            h.next=nd\n",
    "            h=h.next\n",
    "        return hh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1_sum = \"\"\n",
    "        l2_sum = \"\"\n",
    "        p1 = l1\n",
    "        p2 = l2\n",
    "        while p1 is not None:\n",
    "            l1_sum += str(p1.val)\n",
    "            p1 = p1.next\n",
    "        while p2 is not None:\n",
    "            l2_sum += str(p2.val)\n",
    "            p2 = p2.next\n",
    "\n",
    "        num1 = int(l1_sum)\n",
    "        num2 = int(l2_sum)\n",
    "        nums_sum_str = str(num1 + num2)\n",
    "        dummy = ListNode()\n",
    "        tail = dummy\n",
    "        for char in nums_sum_str:\n",
    "            node = ListNode(int(char))\n",
    "            tail.next = node\n",
    "            tail = tail.next\n",
    "\n",
    "        return dummy.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack1 = []\n",
    "        stack2 = []\n",
    "        while l1 or l2:\n",
    "            if l1:\n",
    "                stack1.append(l1.val)\n",
    "                l1 = l1.next\n",
    "            if l2:\n",
    "                stack2.append(l2.val)\n",
    "                l2 = l2.next\n",
    "        cur = None\n",
    "        carry = 0\n",
    "        while stack1 or stack2 or carry:\n",
    "            val1 = stack1.pop() if stack1 else 0\n",
    "            val2 = stack2.pop() if stack2 else 0\n",
    "            total = val1 + val2 + carry\n",
    "            carry = total // 10\n",
    "            temp = ListNode(total % 10)\n",
    "            if cur:\n",
    "                temp.next = cur\n",
    "                cur = temp\n",
    "            else:\n",
    "                cur = temp\n",
    "        return cur"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        stack_1 = []\n",
    "        stack_2 = []\n",
    "        while l1:\n",
    "            stack_1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        \n",
    "        while l2:\n",
    "            stack_2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "\n",
    "        following = None\n",
    "        carry = 0\n",
    "        while stack_1 or stack_2:\n",
    "            num_1 = stack_1.pop() if stack_1 else 0\n",
    "            num_2 = stack_2.pop() if stack_2 else 0\n",
    "            temp = (carry + num_1 + num_2) % 10\n",
    "            carry = (carry + num_1 + num_2) // 10\n",
    "            curr = ListNode(temp)\n",
    "            curr.next = following\n",
    "            following = curr\n",
    "        \n",
    "        if carry:\n",
    "            curr = ListNode(carry)\n",
    "            curr.next = following\n",
    "            following = curr\n",
    "\n",
    "        return following"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "\n",
    "        def reverse(root):\n",
    "            if not root:\n",
    "                return root\n",
    "            pre = None\n",
    "            cur = root\n",
    "            while cur:\n",
    "                nxt = cur.next\n",
    "                cur.next = pre\n",
    "                pre, cur = cur, nxt\n",
    "            return pre\n",
    "\n",
    "        def _add(l1, l2, carry):\n",
    "            \n",
    "            if l1 is None and l2 is None:\n",
    "                return ListNode(carry) if carry else None\n",
    "            if l1 is None:\n",
    "                l1, l2 = l2, l1\n",
    "\n",
    "            carry += l1.val + (l2.val if l2 else 0)\n",
    "            l1.val = carry % 10\n",
    "            l1.next = _add(l1.next, l2.next if l2 else None, carry // 10)\n",
    "            return l1\n",
    "\n",
    "        rev_l1 = reverse(l1)\n",
    "        rev_l2 = reverse(l2)\n",
    "\n",
    "        rev_root = _add(rev_l1, rev_l2, 0)               \n",
    "        return reverse(rev_root)\n",
    "\n",
    "                    \n",
    "\n",
    "\n",
    "\n",
    "            \n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def reverList(self,head):\n",
    "        pre=None\n",
    "        cur=head\n",
    "        while cur:\n",
    "            temp=cur.next\n",
    "            cur.next=pre\n",
    "            pre=cur\n",
    "            cur=temp\n",
    "        return pre\n",
    "    \n",
    "    def addtwoSum(self,l1,l2):\n",
    "        cur=dummy=ListNode()\n",
    "        carry=0\n",
    "        while l1 or l2 or carry:\n",
    "            if l1: carry=carry+l1.val\n",
    "            if l2: carry=carry+l2.val\n",
    "            cur.next=ListNode(carry%10)\n",
    "            carry=carry//10\n",
    "            cur=cur.next\n",
    "            if l1: l1=l1.next\n",
    "            if l2: l2=l2.next\n",
    "\n",
    "        return dummy.next\n",
    "    \n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        reverl1=self.reverList(l1)\n",
    "        reverl2=self.reverList(l2)\n",
    "        addresult=self.addtwoSum(reverl1,reverl2)\n",
    "        result=self.reverList(addresult)\n",
    "        return result\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\r\n",
    "# class ListNode:\r\n",
    "#     def __init__(self, val=0, next=None):\r\n",
    "#         self.val = val\r\n",
    "#         self.next = next\r\n",
    "\r\n",
    "\r\n",
    "def rev(head):\r\n",
    "    cur, pre = head, None\r\n",
    "    while cur:\r\n",
    "        nxt = cur.next\r\n",
    "        cur.next = pre\r\n",
    "        pre = cur\r\n",
    "        cur = nxt\r\n",
    "    return pre\r\n",
    "\r\n",
    "\r\n",
    "class Solution:\r\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\r\n",
    "        l1 = rev(l1)\r\n",
    "        l2 = rev(l2)\r\n",
    "\r\n",
    "        cur = dummy = ListNode()\r\n",
    "        carry = 0\r\n",
    "        while l1 or l2 or carry:\r\n",
    "            carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)\r\n",
    "            cur.next = ListNode(val=carry % 10)\r\n",
    "            carry //= 10\r\n",
    "            cur = cur.next\r\n",
    "            if l1:\r\n",
    "                l1 = l1.next\r\n",
    "            if l2:\r\n",
    "                l2 = l2.next\r\n",
    "        return rev(dummy.next)\r\n",
    "\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        #Optional 可选参数\n",
    "        def decodeNode(ln: ListNode) -> str:\n",
    "            snum = \"\"\n",
    "            i = ln\n",
    "            while(i != None):\n",
    "                snum += str(i.val)\n",
    "                i = i.next\n",
    "            return snum\n",
    "\n",
    "        def encodeNode(n: int) -> ListNode:\n",
    "            sn = str(n)[::-1]\n",
    "            # print(sn)\n",
    "            lnnext = ListNode(val=int(sn[0]))\n",
    "            for i in range(1,len(sn)):\n",
    "                lnnum = ListNode(int(sn[i]),lnnext)\n",
    "                lnnext = lnnum\n",
    "            return lnnext\n",
    "\n",
    "            \n",
    "        s1 = decodeNode(l1)\n",
    "        s2 = decodeNode(l2)\n",
    "        \n",
    "        ia = int(s1) + int(s2)\n",
    "        # print(s1,s2,ia)\n",
    "        return encodeNode(ia)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        def reverse(l):\n",
    "            pre = None\n",
    "            cur = l\n",
    "            while cur:\n",
    "                tmp = cur.next\n",
    "                cur.next = pre\n",
    "                pre = cur\n",
    "                cur = tmp\n",
    "            return pre\n",
    "        L1, L2 = [], []\n",
    "        while l1:\n",
    "            L1.append(l1)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            L2.append(l2)\n",
    "            l2 = l2.next\n",
    "\n",
    "        up = 0\n",
    "        res = []\n",
    "        while L1 or L2 or up:\n",
    "            val = up\n",
    "            if L1:\n",
    "                val += L1.pop().val\n",
    "            if L2:\n",
    "                val += L2.pop().val\n",
    "            if val>=10:\n",
    "                val-=10\n",
    "                up = 1\n",
    "            else:\n",
    "                up = 0\n",
    "            res.append(ListNode(val))\n",
    "\n",
    "        for i in range(len(res)-1, -1, -1):\n",
    "            if i == 0:\n",
    "                res[i].next = None\n",
    "            else:\n",
    "                res[i].next = res[i-1]            \n",
    "        return res[-1]\n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 反转链表\n",
    "        pre=None\n",
    "        cur=head # 将当前指针指向首元结点\n",
    "        while cur:\n",
    "            nxt=cur.next\n",
    "            cur.next=pre\n",
    "            pre=cur\n",
    "            cur=nxt\n",
    "        return pre\n",
    "        \n",
    "    def resultList(self, l1: Optional[ListNode] , l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 将两个链表进行相加运算\n",
    "        p=ass=ListNode(None)\n",
    "        carry=0\n",
    "        while l1 or l2:\n",
    "            temp=(l1.val if l1 else 0)+(l2.val if l2 else 0)+carry\n",
    "            p.next=ListNode(temp%10)\n",
    "            p=p.next\n",
    "            carry=temp//10 # 取整\n",
    "            l1=l1.next if l1 else 0\n",
    "            l2=l2.next if l2 else 0\n",
    "        if carry:\n",
    "            p.next=ListNode(1)\n",
    "        return ass.next\n",
    "    \n",
    "    def addTwoNumbers(self, l1: Optional[ListNode] , l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1=self.reverseList(l1) # 将两个链表进行反转操作\n",
    "        l2=self.reverseList(l2)\n",
    "        l3=self.resultList(l1,l2)\n",
    "        return self.reverseList(l3)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def _reverser(self, cur: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 双指针迭代-反转\n",
    "        # pred=sentienlle=ListNode()\n",
    "        pred = None\n",
    "        while cur:\n",
    "            temp=cur.next\n",
    "            cur.next=pred\n",
    "            pred=cur\n",
    "            cur=temp\n",
    "        return pred\n",
    "\n",
    "    def _addTwo(self, l1: Optional[ListNode], l2: Optional[ListNode], carry=0) -> Optional[ListNode]:\n",
    "        # 递归-两数相加\n",
    "        if l1 is None and l2 is None:\n",
    "            return ListNode(carry) if carry else None\n",
    "        # 设置假定l1是最长的那个\n",
    "        if l1 is None:\n",
    "            l1,l2=l2,l1\n",
    "        carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "        l1.val = carry%10\n",
    "        l1.next = self._addTwo(l1.next, l2.next if l2 else None,carry=carry//10)\n",
    "        return l1\n",
    "\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self._reverser(l1)\n",
    "        l2 = self._reverser(l2)\n",
    "        l1 = self._addTwo(l1, l2)\n",
    "        return self._reverser(l1)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # reverse the linked list\n",
    "        l1 = self.reverseList(l1)\n",
    "        l2 = self.reverseList(l2)\n",
    "        l3 = self.addTwo(l1, l2)\n",
    "        return self.reverseList(l3)\n",
    "\n",
    "\n",
    "    def addTwo(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        carry = 0\n",
    "        dummyHead = ListNode(0)\n",
    "        cur = dummyHead\n",
    "        while l1 or l2:\n",
    "            x = 0 if l1 == None else l1.val\n",
    "            y = 0 if l2 == None else l2.val\n",
    "            sum = 0\n",
    "            sum += (x + y + carry)\n",
    "\n",
    "            carry = sum // 10\n",
    "            sum = sum % 10\n",
    "\n",
    "            cur.next = ListNode(sum)\n",
    "            cur = cur.next\n",
    "\n",
    "            if l1: l1 = l1.next\n",
    "            if l2: l2 = l2.next\n",
    "        if carry != 0:\n",
    "            cur.next = ListNode(carry)\n",
    "        return dummyHead.next\n",
    "\n",
    "\n",
    "    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        pre = None\n",
    "        cur = head\n",
    "        while cur:\n",
    "            tmp = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = tmp\n",
    "        return pre\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "def fanzhuan(l: Optional[ListNode])-> Optional[ListNode]:\n",
    "        cur = l\n",
    "        pre = None\n",
    "        while cur:\n",
    "            nxt = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = nxt\n",
    "        return pre\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        p1 = fanzhuan(l1)\n",
    "        p2 = fanzhuan(l2)\n",
    "        p3 = dummy = ListNode()\n",
    "        carry = 0\n",
    "        while p1 or p2 or carry:\n",
    "            if p1: carry += p1.val\n",
    "            if p2: carry += p2.val\n",
    "            p3.next = ListNode(carry % 10)  # 每个节点保存一个数位\n",
    "            carry //= 10  # 新的进位\n",
    "            p3 = p3.next  # 下一个节点\n",
    "            if p1: p1 = p1.next  # 下一个节点\n",
    "            if p2: p2 = p2.next  # 下一个节点\n",
    "\n",
    "        return fanzhuan(dummy.next)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        #反转链表\n",
    "        pre1=None\n",
    "        cur1=l1\n",
    "        while cur1:\n",
    "            nxt1 = cur1.next\n",
    "            cur1.next = pre1\n",
    "            pre1 = cur1\n",
    "            cur1 = nxt1\n",
    "        #此时l1头节点pre1\n",
    "        pre2=None\n",
    "        cur2=l2\n",
    "        while cur2:\n",
    "            nxt2 = cur2.next\n",
    "            cur2.next = pre2\n",
    "            pre2 = cur2\n",
    "            cur2 = nxt2\n",
    "        #此时l2头节点pre2:\n",
    "        cur1 = pre1\n",
    "        cur2 = pre2\n",
    "        dummy = cur1\n",
    "        flag = 0\n",
    "        while cur1 and cur2:\n",
    "            cur1.val = cur1.val + cur2.val + flag\n",
    "            flag = 0\n",
    "            if cur1.val >9:\n",
    "                cur1.val -= 10\n",
    "                flag +=1\n",
    "            pre1 = cur1\n",
    "            cur1 = cur1.next\n",
    "            cur2 = cur2.next\n",
    "\n",
    "        while cur1:\n",
    "            cur1.val = cur1.val + flag\n",
    "            flag = 0\n",
    "            if cur1.val >9:\n",
    "                cur1.val -= 10\n",
    "                flag +=1\n",
    "            pre1 = cur1\n",
    "            cur1 = cur1.next\n",
    "\n",
    "        while cur2:\n",
    "            cur1 = ListNode(val = 0)\n",
    "            pre1.next = cur1\n",
    "            cur1.val = cur2.val + flag\n",
    "            flag = 0\n",
    "            if cur1.val >9:\n",
    "                cur1.val -= 10\n",
    "                flag +=1\n",
    "            pre1 = cur1\n",
    "            cur2 = cur2.next\n",
    "            cur1 = cur1.next\n",
    "\n",
    "        if flag == 1:\n",
    "            cur1 = ListNode(val = 1)\n",
    "            pre1.next = cur1\n",
    "\n",
    "        pre1=None\n",
    "        cur1=dummy\n",
    "        while cur1:\n",
    "            nxt1 = cur1.next\n",
    "            cur1.next = pre1\n",
    "            pre1 = cur1\n",
    "            cur1 = nxt1\n",
    "        return pre1\n",
    "\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1, s2 = [], []\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        ans = None\n",
    "        carry = 0\n",
    "        while s1 or s2 or carry != 0:\n",
    "            a = 0 if not s1 else s1.pop()\n",
    "            b = 0 if not s2 else s2.pop()\n",
    "            cur = a + b + carry\n",
    "            carry = cur // 10\n",
    "            cur %= 10\n",
    "            curnode = ListNode(cur)\n",
    "            curnode.next = ans\n",
    "            ans = curnode\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1 = []\n",
    "        s2 = []\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1=l1.next\n",
    "        \n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        \n",
    "        carry = 0\n",
    "        ans = None\n",
    "        while s1 or s2 or carry != 0:\n",
    "            if s1:\n",
    "                a = s1.pop()\n",
    "            else:\n",
    "                a = 0\n",
    "            if s2:\n",
    "                b = s2.pop()\n",
    "            else:\n",
    "                b = 0\n",
    "            num = a + b + carry\n",
    "            carry = num // 10\n",
    "            cur = num % 10\n",
    "            node = ListNode(cur)\n",
    "            node.next = ans\n",
    "            ans = node\n",
    "        \n",
    "        return ans\n",
    "\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def _reverser(self, cur: Optional[ListNode], pred: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 递归-反转\n",
    "        if cur is None:\n",
    "            return pred\n",
    "        res = self._reverser(cur.next, cur)\n",
    "        cur.next = pred\n",
    "        return res\n",
    "\n",
    "    def _addTwo(self, l1: Optional[ListNode], l2: Optional[ListNode], carry=0) -> Optional[ListNode]:\n",
    "        # 递归-两数相加\n",
    "        if l1 is None and l2 is None:\n",
    "            return ListNode(carry) if carry else None\n",
    "        # 设置假定l1是最长的那个\n",
    "        if l1 is None:\n",
    "            l1,l2=l2,l1\n",
    "        carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "        l1.val = carry%10\n",
    "        l1.next = self._addTwo(l1.next, l2.next if l2 else None,carry=carry//10)\n",
    "        return l1\n",
    "\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self._reverser(l1, None)\n",
    "        l2 = self._reverser(l2, None)\n",
    "        l1 = self._addTwo(l1, l2)\n",
    "        return self._reverser(l1, None)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        s1, s2 = [], []\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        ans = None\n",
    "        carry = 0\n",
    "        while s1 or s2 or carry != 0:\n",
    "            a = 0 if not s1 else s1.pop()\n",
    "            b = 0 if not s2 else s2.pop()\n",
    "            cur = a + b + carry\n",
    "            carry = cur // 10\n",
    "            cur %= 10\n",
    "            curnode = ListNode(cur)\n",
    "            curnode.next = ans\n",
    "            ans = curnode\n",
    "        return ans\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "#梁佟辉方法：反转链表相加再反转链表\n",
    "# class Solution:\n",
    "#     def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "#         #反转链表\n",
    "#         pre1=None\n",
    "#         cur1=l1\n",
    "#         while cur1:\n",
    "#             nxt1 = cur1.next\n",
    "#             cur1.next = pre1\n",
    "#             pre1 = cur1\n",
    "#             cur1 = nxt1\n",
    "#         #此时l1头节点pre1\n",
    "#         pre2=None\n",
    "#         cur2=l2\n",
    "#         while cur2:\n",
    "#             nxt2 = cur2.next\n",
    "#             cur2.next = pre2\n",
    "#             pre2 = cur2\n",
    "#             cur2 = nxt2\n",
    "#         #此时l2头节点pre2:\n",
    "#         cur1 = pre1\n",
    "#         cur2 = pre2\n",
    "#         dummy = cur1\n",
    "#         flag = 0\n",
    "#         while cur1 and cur2:\n",
    "#             cur1.val = cur1.val + cur2.val + flag\n",
    "#             flag = 0\n",
    "#             if cur1.val >9:\n",
    "#                 cur1.val -= 10\n",
    "#                 flag +=1\n",
    "#             pre1 = cur1\n",
    "#             cur1 = cur1.next\n",
    "#             cur2 = cur2.next\n",
    "\n",
    "#         while cur1:\n",
    "#             cur1.val = cur1.val + flag\n",
    "#             flag = 0\n",
    "#             if cur1.val >9:\n",
    "#                 cur1.val -= 10\n",
    "#                 flag +=1\n",
    "#             pre1 = cur1\n",
    "#             cur1 = cur1.next\n",
    "\n",
    "#         while cur2:\n",
    "#             cur1 = ListNode(val = 0)\n",
    "#             pre1.next = cur1\n",
    "#             cur1.val = cur2.val + flag\n",
    "#             flag = 0\n",
    "#             if cur1.val >9:\n",
    "#                 cur1.val -= 10\n",
    "#                 flag +=1\n",
    "#             pre1 = cur1\n",
    "#             cur2 = cur2.next\n",
    "#             cur1 = cur1.next\n",
    "\n",
    "#         if flag == 1:\n",
    "#             cur1 = ListNode(val = 1)\n",
    "#             pre1.next = cur1\n",
    "\n",
    "#         pre1=None\n",
    "#         cur1=dummy\n",
    "#         while cur1:\n",
    "#             nxt1 = cur1.next\n",
    "#             cur1.next = pre1\n",
    "#             pre1 = cur1\n",
    "#             cur1 = nxt1\n",
    "#         return pre1\n",
    "\n",
    "#0x3f:\n",
    "class Solution:\n",
    "    # 视频讲解 https://www.bilibili.com/video/BV1sd4y1x7KN/\n",
    "    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        pre = None\n",
    "        cur = head\n",
    "        while cur:\n",
    "            nxt = cur.next\n",
    "            cur.next = pre\n",
    "            pre = cur\n",
    "            cur = nxt\n",
    "        return pre\n",
    "\n",
    "    def addTwo(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        cur = dummy = ListNode()  # 哨兵节点\n",
    "        carry = 0  # 进位\n",
    "        while l1 or l2 or carry:  # 有一个不是空节点，或者还有进位，就继续迭代\n",
    "            if l1: carry += l1.val  # 节点值和进位加在一起\n",
    "            if l2: carry += l2.val  # 节点值和进位加在一起\n",
    "            cur.next = ListNode(carry % 10)  # 每个节点保存一个数位\n",
    "            carry //= 10  # 新的进位\n",
    "            cur = cur.next  # 下一个节点\n",
    "            if l1: l1 = l1.next  # 下一个节点\n",
    "            if l2: l2 = l2.next  # 下一个节点\n",
    "        return dummy.next  # 哨兵节点的下一个节点就是头节点\n",
    "\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self.reverseList(l1)\n",
    "        l2 = self.reverseList(l2)  # l1 和 l2 反转后，就变成【2. 两数相加】了\n",
    "        l3 = self.addTwo(l1, l2)\n",
    "        return self.reverseList(l3)  # 计算完毕后再反转\n",
    "\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        s1, s2 = [], []\n",
    "        while l1:\n",
    "            s1.append(l1.val)\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            s2.append(l2.val)\n",
    "            l2 = l2.next\n",
    "        ans = None\n",
    "        carry = 0\n",
    "        while s1 or s2 or carry:\n",
    "            a = 0 if not s1 else s1.pop()\n",
    "            b = 0 if not s2 else s2.pop()\n",
    "            total = a + b + carry\n",
    "            carry = total // 10\n",
    "            cur = total % 10\n",
    "            curnode = ListNode(cur)\n",
    "            curnode.next = ans\n",
    "            ans = curnode\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        st1=[]\n",
    "        st2=[]\n",
    "        while l1:\n",
    "            st1.append(l1.val)\n",
    "            l1=l1.next\n",
    "        while l2:\n",
    "            st2.append(l2.val)\n",
    "            l2=l2.next\n",
    "        carry=0\n",
    "        dummy=ListNode(0)\n",
    "        while st1 or st2 or carry:\n",
    "            v1=st1.pop() if st1 else 0\n",
    "            v2=st2.pop() if st2 else 0\n",
    "            sum=v1+v2+carry\n",
    "            carry=1 if sum>=10 else 0\n",
    "            sum=sum-10 if sum>=10 else sum\n",
    "            cur=ListNode(sum)\n",
    "            cur.next=dummy.next\n",
    "            dummy.next=cur\n",
    "        return dummy.next\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def reverseList(self,head:Optional[ListNode]):\n",
    "        if head is None or head.next is None:\n",
    "            return head\n",
    "        new_head=self.reverseList(head.next)\n",
    "        head.next.next=head\n",
    "        head.next=None\n",
    "        return new_head\n",
    "    \n",
    "    def addTwo(self,l1:Optional[ListNode],l2:Optional[ListNode],c=0):\n",
    "        if l1 is None and l2 is None:\n",
    "            return ListNode(c) if c else None\n",
    "        if l1 is None:\n",
    "            l1,l2=l2,l1\n",
    "        c+=l1.val+(l2.val if l2 else 0)\n",
    "        l1.val=c%10\n",
    "        l1.next=self.addTwo(l1.next,l2.next if l2 else None,c//10)\n",
    "        return l1\n",
    "\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1,l2=self.reverseList(l1),self.reverseList(l2)\n",
    "        l3=self.addTwo(l1,l2)\n",
    "        return self.reverseList(l3)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\r\n",
    "# class ListNode:\r\n",
    "#     def __init__(self, val=0, next=None):\r\n",
    "#         self.val = val\r\n",
    "#         self.next = next\r\n",
    "class Solution:\r\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\r\n",
    "        s1 = \"\"\r\n",
    "        p = l1\r\n",
    "        while p:\r\n",
    "            s1 += str(p.val)\r\n",
    "            p = p.next\r\n",
    "        s2 = \"\"\r\n",
    "        p = l2\r\n",
    "        while p:\r\n",
    "            s2 += str(p.val)\r\n",
    "            p = p.next\r\n",
    "        s = str(int(s1) + int(s2))\r\n",
    "        dummy = ListNode()\r\n",
    "        p0 = dummy\r\n",
    "        for i in range(len(s)):\r\n",
    "            p = ListNode(val=int(s[i]))\r\n",
    "            p0.next = p\r\n",
    "            p0 = p\r\n",
    "        p0.next = None\r\n",
    "        return dummy.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def _reverser(self, cur: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 迭代-反转\n",
    "        pred,cur = None,cur\n",
    "        while cur:\n",
    "            temp=cur.next\n",
    "            cur.next=pred\n",
    "            pred=cur\n",
    "            cur=temp\n",
    "        return pred\n",
    "\n",
    "    def _addTwo(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 迭代-两数相加\n",
    "        # sentienlle=cur=ListNode(next=l1)     # 这是错误的做法，并不是从新构造l1而是构造cur\n",
    "        sentienlle=cur=ListNode()\n",
    "        carry=0\n",
    "        while(l1 or l2 or carry):\n",
    "            carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "            cur.next = ListNode(carry%10)               # 构造cur\n",
    "            cur=cur.next\n",
    "            if l1:l1=l1.next\n",
    "            if l2:l2=l2.next\n",
    "            carry=carry//10\n",
    "        return sentienlle.next\n",
    "        \n",
    "\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self._reverser(l1)\n",
    "        l2 = self._reverser(l2)\n",
    "        l1 = self._addTwo(l1, l2)\n",
    "        return self._reverser(l1)\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def reverseList(self, cur: Optional[ListNode], pre: Optional[ListNode])-> Optional[ListNode]:\n",
    "        # 递归反转列表\n",
    "        if cur is None:\n",
    "            return pre\n",
    "        res = self.reverseList(cur.next, cur)\n",
    "        cur.next = pre\n",
    "        return res\n",
    "\n",
    "    def addTwo(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        # 迭代两数相加\n",
    "        carry = 0\n",
    "        cur = dummy = ListNode()\n",
    "        while l1 or l2 or carry:\n",
    "            carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "            cur.next  = ListNode(carry % 10)\n",
    "            carry = carry // 10\n",
    "            cur = cur.next\n",
    "            if l1: l1 = l1.next\n",
    "            if l2: l2 = l2.next\n",
    "        return dummy.next\n",
    "\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        l1 = self.reverseList(l1, None)\n",
    "        l2 = self.reverseList(l2, None)\n",
    "        res = self.addTwo(l1, l2)\n",
    "        return self.reverseList(res, None)\n",
    "        \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        root_node = ListNode()\n",
    "        iter_node = root_node\n",
    "        curr = 0\n",
    "        while l1 or l2 or curr:\n",
    "            if l1 is not None:\n",
    "                curr += l1.val\n",
    "                l1 = l1.next\n",
    "            if l2 is not None:\n",
    "                curr += l2.val\n",
    "                l2 = l2.next\n",
    "\n",
    "            new_node = ListNode(val=curr % 10, next=None)\n",
    "            iter_node.next = new_node\n",
    "            iter_node = new_node\n",
    "            curr = curr // 10\n",
    "        return root_node.next\n",
    "\n",
    "            \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        res = ListNode((l1.val + l2.val) % 10)\n",
    "        jinwei = (int(l1.val) + int(l2.val)) // 10\n",
    "        tmp1 = l1.next\n",
    "        tmp2 = l2.next\n",
    "        tmp3 = res\n",
    "        while tmp1 != None and tmp2 != None:\n",
    "            tmp3.next = ListNode((tmp1.val + tmp2.val + jinwei) % 10)\n",
    "            jinwei = int(tmp1.val + tmp2.val + jinwei) // 10\n",
    "            tmp3 = tmp3.next\n",
    "            tmp1 = tmp1.next\n",
    "            tmp2 = tmp2.next\n",
    "        while tmp1 != None:\n",
    "            tmp3.next = ListNode((tmp1.val + jinwei) % 10)\n",
    "            jinwei = int(tmp1.val + jinwei) // 10\n",
    "            tmp3 = tmp3.next\n",
    "            tmp1 = tmp1.next\n",
    "        while tmp2 != None:\n",
    "            tmp3.next = ListNode((tmp2.val + jinwei) % 10)\n",
    "            jinwei = int(tmp2.val + jinwei) // 10\n",
    "            tmp3 = tmp3.next\n",
    "            tmp2 = tmp2.next\n",
    "        if jinwei != 0:\n",
    "            tmp3.next = ListNode(jinwei)\n",
    "        return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        dummy_head = ListNode(0)\n",
    "        cur = dummy_head\n",
    "        carry = 0\n",
    "        while l1 or l2 or carry:\n",
    "            if l1:\n",
    "                carry += l1.val\n",
    "                l1 = l1.next\n",
    "            if l2:\n",
    "                carry += l2.val\n",
    "                l2 = l2.next\n",
    "            cur.next = ListNode(carry % 10)\n",
    "            cur = cur.next\n",
    "            carry //= 10\n",
    "        return dummy_head.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        car,res,res=0,None,ListNode(0)\n",
    "        root=res\n",
    "        while l1 or l2 or car:\n",
    "            v1,v2=0,0\n",
    "            if l1:\n",
    "                v1=l1.val\n",
    "                l1=l1.next\n",
    "            \n",
    "            if l2:\n",
    "                v2=l2.val\n",
    "                l2=l2.next\n",
    "                \n",
    "            val=(v1+v2+car)%10\n",
    "            car=int((v1+v2+car)/10)\n",
    "            \n",
    "            res.next=ListNode(val)\n",
    "            res=res.next\n",
    "            \n",
    "        return root.next\n",
    "            \n",
    "            \n",
    "            \n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        \n",
    "        if l1 is None and l2 is None:\n",
    "            return None\n",
    "        else:\n",
    "            l1_next = None\n",
    "            l2_next = None\n",
    "            summary = 0\n",
    "            carry = 0\n",
    "            \n",
    "            if l1 is not None:\n",
    "                summary += l1.val\n",
    "                l1_next = l1.next\n",
    "            \n",
    "            if l2 is not None:\n",
    "                summary += l2.val\n",
    "                l2_next = l2.next\n",
    "            \n",
    "            carry = summary // 10\n",
    "            mod = summary % 10\n",
    "            result = ListNode(mod)\n",
    "\n",
    "            if carry != 0:\n",
    "                if l1_next is not None:\n",
    "                    l1_next.val += carry\n",
    "                    result.next = self.addTwoNumbers(l1_next, l2_next)\n",
    "                elif l2_next is not None:\n",
    "                    l2_next.val += carry\n",
    "                    result.next = self.addTwoNumbers(l1_next, l2_next)\n",
    "                elif l1_next is None and l2_next is None:\n",
    "                    result.next = ListNode(carry)\n",
    "            else:\n",
    "                    result.next = self.addTwoNumbers(l1_next, l2_next)                \n",
    "            return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "#     def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "#         l_out = ListNode(0)\n",
    "#         l_sum = l_out\n",
    "#         while l1 or l2:\n",
    "#             if l1 == None: l1 = ListNode(0)\n",
    "#             if l2 == None: l2 = ListNode(0)\n",
    "                \n",
    "#             sum = l1.val + l2.val +l_sum.val\n",
    "#             sum_carry = sum // 10\n",
    "#             l_sum.val = sum % 10\n",
    "#             if l1.next == None and l2.next == None and sum_carry == 0:\n",
    "#                 l_sum.next = None\n",
    "#                 break\n",
    "                \n",
    "#             else: l_sum.next = ListNode(sum_carry)\n",
    "\n",
    "#             l1 = l1.next\n",
    "#             l2 = l2.next\n",
    "#             l_sum = l_sum.next\n",
    "            \n",
    "        \n",
    "#         return l_out\n",
    "\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        l_out = ListNode(0)\n",
    "        l_sum = l_out\n",
    "        carry = 0\n",
    "        x = l1.val\n",
    "        y = l2.val\n",
    "        while l1 or l2:\n",
    "            if l1 == None: x = 0\n",
    "            else: \n",
    "                x = l1.val\n",
    "                l1 = l1.next\n",
    "            if l2 == None: y = 0\n",
    "            else: \n",
    "                y = l2.val\n",
    "                l2 = l2.next\n",
    "                      \n",
    "            sum = x + y + carry\n",
    "            \n",
    "            carry = sum // 10\n",
    "\n",
    "            l_sum.next = ListNode(sum % 10)\n",
    "            l_sum = l_sum.next\n",
    "        \n",
    "        if carry == 1:\n",
    "            l_sum.next = ListNode(1)\n",
    "               \n",
    "        return l_out.next\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        a,b = l1,l2\n",
    "        f1 = ListNode(a.val+b.val)\n",
    "        f2 = f1\n",
    "        while a.next or b.next:\n",
    "            if f1.val>=10:\n",
    "                f1.val =f1.val-10\n",
    "                flag = 1\n",
    "            else:\n",
    "                flag=0\n",
    "            if not a.next:\n",
    "                a.val = 0\n",
    "            else:\n",
    "                a = a.next\n",
    "            if not b.next:\n",
    "                b.val = 0\n",
    "            else:\n",
    "                b = b.next\n",
    "            f1.next =ListNode(a.val+b.val+flag)\n",
    "            print(f1.next.val)\n",
    "            f1 = f1.next\n",
    "        if f1.val>=10:\n",
    "            f1.val-=10\n",
    "            f1.next = ListNode(1)\n",
    "            \n",
    "\n",
    "        return f2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: 'ListNode', l2: 'ListNode') -> 'ListNode':\n",
    "        num1 = 0\n",
    "        num2 = 0\n",
    "        # number1\n",
    "        node = l1\n",
    "        k = 1\n",
    "        while(node.next != None):\n",
    "            print(node.val)\n",
    "            num1 = num1 + node.val*k\n",
    "            k = k*10\n",
    "            node = node.next\n",
    "        num1 = num1 + node.val*k\n",
    "        # number2\n",
    "        node = l2\n",
    "        k = 1\n",
    "        while(node.next != None):\n",
    "            num2 = num2 + node.val*k\n",
    "            k = k*10\n",
    "            node = node.next\n",
    "        num2 = num2 + node.val*k\n",
    "        sum = num1 + num2\n",
    "        sumlist = []\n",
    "        while(sum!=0):\n",
    "            sumlist.append(sum%10)\n",
    "            sum = sum//10\n",
    "        return sumlist if(sumlist != []) else [0]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        ans = ListNode(0)  #新建一个节点，初始值为0      \n",
    "        temp = ans\n",
    "        tempsum = 0\n",
    "        \n",
    "        while True:\n",
    "            if (l1 != None):\n",
    "                tempsum = l1.val + tempsum                     #l1链表节点值添加到总和里\n",
    "                l1 = l1.next                                   #指针指向下一个节点\n",
    "            if (l2 != None):\n",
    "                tempsum = tempsum + l2.val                     #l2链表节点值添加到总和里\n",
    "                l2 = l2.next                                   #指针指向下一个节点    \n",
    "            temp.val = tempsum % 10                            #取余数（满十进位），赋值当前节点值 \n",
    "            print(tempsum)\n",
    "            tempsum  = int(tempsum / 10)                       #获取进位数赋值给总和（比如tempsum为10则进1位，否则进位为0），下一次节点相加，从新的总和开始。\n",
    "            if l1 == None  and l2 == None and tempsum == 0:    #直到没有进位了，同时节点位空了，跳出循环。（这里加上tempsum==0条件是因为，最后两个节\n",
    "                break                                          #点和值可能大于10）                           \n",
    "            temp.next = ListNode(0)                            #新建下一个节点，存放和\n",
    "            temp = temp.next                                   #指针指向下一个节点\n",
    "        return ans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        # 1. 处理其中一个链表为空的情况，仅需返回另外一个链表即可\n",
    "        if not l1:\n",
    "            return l2\n",
    "        if not l2:\n",
    "            return l1\n",
    "        \n",
    "        # 2. 设置两个链表指针，从链表头结点开始依次对对应的链表结点相加\n",
    "        res=ListNode(0)   # 结果链表，同样使用哑结点来进行代码简化\n",
    "        carrier=0         # 来自于上一位相加结果的进位数值\n",
    "        respos=res        # 结果链表指针\n",
    "        pos1=l1           # 链表1指针\n",
    "        pos2=l2           # 链表2指针\n",
    "\n",
    "        while pos1 or pos2 or carrier:\n",
    "            # 2.1 计算本位结果和进位\n",
    "            temp=(pos1.val if pos1 else 0)+(pos2.val if pos2 else 0)+carrier\n",
    "            print(temp)\n",
    "            value=temp%10\n",
    "            carrier=temp//10   #注意python3中的整数除法为双斜线\n",
    "            respos.next=ListNode(value)\n",
    "            \n",
    "            # 2.2 更新各个链表的指针\n",
    "            pos1=pos1.next if pos1 else pos1\n",
    "            pos2=pos2.next if pos2 else pos2\n",
    "            respos=respos.next\n",
    "\n",
    "        return res.next\n",
    "        \n",
    "        \n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "        \n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        relist = ListNode(0)\n",
    "        tlist = relist\n",
    "        carry = 0\n",
    "        while l1 or l2:\n",
    "            n1 = l1.val if l1 else 0\n",
    "            n2 = l2.val if l2 else 0\n",
    "            s = n1 + n2 + carry\n",
    "            carry = s//10\n",
    "            print(s,carry)\n",
    "            tlist.next = ListNode(s%10)\n",
    "            tlist = tlist.next\n",
    "            \n",
    "            if l1: \n",
    "                l1 = l1.next \n",
    "            if l2:\n",
    "                l2 = l2.next \n",
    "            \n",
    "        if(carry>0):\n",
    "            tlist.next=ListNode(carry)\n",
    "        return relist.next\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"                   \n",
    "        #l1.val表示当前链表的值，l1.next表示链表指针指向下一个节点\n",
    "        #创建头节点\n",
    "        self.head=ListNode(0)\n",
    "        p=self.head\n",
    "        more=0\n",
    "        more1=0\n",
    "        more2=0\n",
    "        while(l1!=None and l2!=None):\n",
    "            value=l1.val+l2.val+more\n",
    "            \n",
    "            data=list(str(value))\n",
    "            \n",
    "            if(len(data)==1):\n",
    "                node=ListNode(int(data[0]))\n",
    "                print(int(data[0]),more)\n",
    "                more=0\n",
    "            else:\n",
    "                node=ListNode(int(data[1]))\n",
    "                print(int(data[1]),more)\n",
    "                more=int(data[0])\n",
    "            \n",
    "            p.next=node\n",
    "            p=p.next\n",
    "            l1=l1.next\n",
    "            l2=l2.next\n",
    "        \n",
    "        if(l1!=None and l2==None):\n",
    "            more1=more\n",
    "        if(l2!=None and l1==None):\n",
    "            more2=more\n",
    "        \n",
    "        while(l1!=None):\n",
    "            value=l1.val+more1\n",
    "            data=list(str(value))\n",
    "            #print(data)\n",
    "            if(len(data)==1):\n",
    "                node=ListNode(int(data[0]))\n",
    "                print(int(data[0]),more1)\n",
    "                more1=0\n",
    "            else:\n",
    "                node=ListNode(int(data[1]))\n",
    "                print(int(data[1]),more1)\n",
    "                more1=int(data[0])\n",
    "            #print(more1)     \n",
    "            p.next=node\n",
    "            p=p.next\n",
    "            l1=l1.next\n",
    "            more=0\n",
    "        while(l2!=None):\n",
    "            value=l2.val+more2\n",
    "            data=list(str(value))\n",
    "            #print(data)\n",
    "            if(len(data)==1):\n",
    "                node=ListNode(int(data[0]))\n",
    "                more2=0\n",
    "            else:\n",
    "                node=ListNode(int(data[1]))\n",
    "                more2=int(data[0])\n",
    "            #print(more)\n",
    "            p.next=node\n",
    "            p=p.next\n",
    "            l2=l2.next\n",
    "            more=0\n",
    "        if(more!=0):\n",
    "            node=ListNode(more)\n",
    "            p.next=node\n",
    "        if(more1!=0):\n",
    "            node=ListNode(more1)\n",
    "            p.next=node\n",
    "        if(more2!=0):\n",
    "            node=ListNode(more2)\n",
    "            p.next=node\n",
    "        p=self.head\n",
    "        p.val=p.next.val\n",
    "        p.next=p.next.next\n",
    "        return p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        head, carry = ListNode(0), 0\n",
    "        node, zero = head, ListNode(0)\n",
    "        while l1 or l2:\n",
    "            if not l1:\n",
    "                l1 = zero\n",
    "            if not l2:\n",
    "                l2 = zero\n",
    "            val = l1.val+l2.val+carry\n",
    "            print(l1.val, l2.val)\n",
    "            carry, val = divmod(val, 10)\n",
    "            node.next = ListNode(val)\n",
    "            node = node.next\n",
    "            l1 = l1.next\n",
    "            l2 = l2.next\n",
    "        if carry:\n",
    "            node.next = ListNode(carry)\n",
    "            carry = 0\n",
    "        return head.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        l3=[]\n",
    "        last=0\n",
    "        while l1.next != None and l2.next != None:\n",
    "            toVal = l1.val+l2.val\n",
    "            curVal = (toVal+last)%10\n",
    "            last = (toVal+last)//10\n",
    "            print(toVal,curVal,last)\n",
    "            l3.append(curVal)\n",
    "            l1=l1.next\n",
    "            l2=l2.next\n",
    "        if l1.next == None and l2.next==None:\n",
    "            last=last+l1.val+l2.val\n",
    "        elif l1.next == None and l2.next != None:\n",
    "            last=last+l1.val\n",
    "            while l2.next != None:\n",
    "                toVal = l2.val+last\n",
    "                curVal = toVal%10\n",
    "                last = toVal//10 \n",
    "                l3.append(curVal)\n",
    "                l2=l2.next\n",
    "            last=last+l2.val\n",
    "        else:\n",
    "            last=last+l2.val\n",
    "            while l1.next != None:\n",
    "                toVal = l1.val+last\n",
    "                curVal = toVal%10\n",
    "                last = toVal//10 \n",
    "                print(toVal,curVal,last)\n",
    "                l3.append(curVal)\n",
    "                l1=l1.next\n",
    "            last=last+l1.val\n",
    "        l3.append(last%10)\n",
    "        if last//10 >=1:\n",
    "            l3.append(last//10)\n",
    "        return l3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        s1=s2=''\n",
    "        while True:\n",
    "            s1+=str(l1.val)\n",
    "            if l1.next==None:\n",
    "                break\n",
    "            l1=l1.next\n",
    "        while True:\n",
    "            s2+=str(l2.val)\n",
    "            if l2.next==None:\n",
    "                break\n",
    "            l2=l2.next\n",
    "        I1=int(s1[::-1])\n",
    "        I2=int(s2[::-1])\n",
    "        I=I1+I2\n",
    "        S=str(I)[::-1]\n",
    "        res=ListNode(int(S[0]))\n",
    "        res1=res\n",
    "        for x in S[1::]:\n",
    "                     res.next=ListNode(int(x))\n",
    "                     res=res.next\n",
    "        return res1\n",
    "        \n",
    "        \n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "def panduan(x):\n",
    "        if x==None:\n",
    "            return 0\n",
    "        else:\n",
    "            return 1\n",
    "\n",
    "def panduan_val(x):\n",
    "        if x==None:\n",
    "            return 0\n",
    "        else:\n",
    "            return x.val\n",
    "\n",
    "class Solution:\n",
    "\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        lsum_hand =ListNode(0)\n",
    "        lsum =lsum_hand\n",
    "        l1_now =l1\n",
    "        l2_now =l2\n",
    "#hand\n",
    "        lsum_jinyi =(panduan_val(l1_now)+panduan_val(l2_now))//10\n",
    "        lsum.val=(panduan_val(l1_now)+panduan_val(l2_now))%10\n",
    "        l1_now=l1_now.next if (l1_now!=None and l1_now.next!=None) else None \n",
    "        l2_now=l2_now.next if (l2_now!=None and l2_now.next!=None) else None\n",
    " #others\n",
    "        while(panduan(l1_now) or panduan(l2_now) or lsum_jinyi==1):\n",
    "            lsum.next=ListNode(0)\n",
    "            lsum=lsum.next\n",
    "            lsum.val = lsum_jinyi\n",
    "            lsum.val += panduan_val(l1_now)+panduan_val(l2_now)\n",
    "            lsum_jinyi = lsum.val//10\n",
    "            lsum.val = lsum.val%10\n",
    "            l1_now=l1_now.next if (l1_now!=None and l1_now.next!=None) else None \n",
    "            l2_now=l2_now.next if (l2_now!=None and l2_now.next!=None) else None\n",
    "        return lsum_hand"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "        \n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        if not l1 and l2: return l2\n",
    "        if not l2 and l1: return l1\n",
    "        if not (l1 and l2): return \n",
    "        L1,L2 = 0,0\n",
    "        m,n = 0,0\n",
    "        # 计算两链表长度并获得两链表的值\n",
    "        tmp1,tmp2 = l1,l2 \n",
    "        while tmp1:\n",
    "            m += 1\n",
    "            tmp1 = tmp1.next\n",
    "        while tmp2:\n",
    "            n += 1\n",
    "            tmp2 = tmp2.next\n",
    "        for i in range(m):\n",
    "            L1 += l1.val*(10**i)\n",
    "            l1 = l1.next\n",
    "        for j in range(n):\n",
    "            L2 += l2.val*(10**j)\n",
    "            l2 = l2.next\n",
    "        # 两链表值家和并生成list\n",
    "        val = int(L1) + int(L2)\n",
    "        tmp = list(str(val))\n",
    "        # list转化成链表，生成链表的步骤如下\n",
    "        node = ListNode(None)\n",
    "        tmp_node = ListNode(None)\n",
    "        while tmp:\n",
    "            if tmp_node.val is None:\n",
    "                tmp_node = ListNode(int(tmp.pop()))\n",
    "                node.next = tmp_node\n",
    "            else:\n",
    "                tmp_node.next = ListNode(int(tmp.pop()))\n",
    "                tmp_node = tmp_node.next\n",
    "        return node.next\n",
    "\n",
    "\n",
    "        \n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        l = ListNode(0)\n",
    "        lres = l\n",
    "        carry = 0\n",
    "\n",
    "        while l1 or l2:\n",
    "            x = l1.val if l1 else 0\n",
    "            y = l2.val if l2 else 0\n",
    "            ds = x + y + carry\n",
    "            carry = ds // 10\n",
    "            ds = ds - carry * 10\n",
    "            lres.next = ListNode(ds)\n",
    "            lres = lres.next\n",
    "            if l1: l1 = l1.next\n",
    "            if l2: l2 = l2.next\n",
    "        if carry > 0:\n",
    "            lres.next = ListNode(carry)\n",
    "        \n",
    "        return l.next\n",
    "\n",
    "        \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode(object):\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    " \n",
    "class Solution(object):\n",
    "    \n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        \"\"\"\n",
    "        :type l1: ListNode\n",
    "        :type l2: ListNode\n",
    "        :rtype: ListNode\n",
    "        \"\"\"\n",
    "        if l1 is None:\n",
    "            return l2\n",
    "        if l2 is None:\n",
    "            return l1\n",
    " \n",
    "        tmp = ListNode(0)\n",
    "        res = tmp\n",
    "        flag = 0\n",
    "        while l1 or l2:\n",
    "            tmpsum = 0\n",
    "            if l1:\n",
    "                tmpsum = l1.val\n",
    "                l1 = l1.next\n",
    "            if l2:\n",
    "                tmpsum += l2.val\n",
    "                l2 = l2.next\n",
    "            tmpres = ((tmpsum + flag) % 10)\n",
    "            flag = ((tmpsum + flag) // 10)\n",
    "            res.next = ListNode(tmpres)\n",
    "            res = res.next\n",
    "        if flag:\n",
    "            res.next = ListNode(1)\n",
    "        res = tmp.next\n",
    "        del tmp\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        ret = ListNode(-1)\n",
    "        ret_c  = ret\n",
    "        c=0\n",
    "        while l1 or l2:\n",
    "            if l1 and l2:\n",
    "                val = l1.val+l2.val+c\n",
    "            if not l1:\n",
    "                val = l2.val+c\n",
    "            if not l2:\n",
    "                 val = l1.val+c\n",
    "            if val<10:\n",
    "                node = ListNode(val)\n",
    "                c=0\n",
    "            else:\n",
    "                c = 1\n",
    "                node = ListNode(val-10)\n",
    "            ret.next =node\n",
    "            ret = node\n",
    "            if l1:\n",
    "                l1 = l1.next\n",
    "            if l2:\n",
    "                l2 = l2.next\n",
    "        if c==1:\n",
    "            node = ListNode(1)\n",
    "            ret.next =node\n",
    "            ret = node            \n",
    "        return ret_c.next\n",
    "                \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        res = ListNode()\n",
    "        temp = res\n",
    "        f = 0\n",
    "        while l1 or l2:           \n",
    "            v1 = l1.val if l1 else 0\n",
    "            v2 = l2.val if l2 else 0\n",
    "            temp.val = v1 + v2 + f\n",
    "            if temp.val >= 10:\n",
    "                temp.val -= 10\n",
    "                f = 1\n",
    "            else:\n",
    "                f = 0\n",
    "            if (l1 and l1.next) or (l2 and l2.next):\n",
    "                temp.next = ListNode()\n",
    "                temp = temp.next\n",
    "            if l1:\n",
    "                l1 = l1.next\n",
    "            if l2:\n",
    "                l2 = l2.next\n",
    "        if f == 1:\n",
    "            temp.next = ListNode(1)\n",
    "        return res\n",
    "            \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        p = l1\n",
    "        res1 = []\n",
    "        while p:\n",
    "            res1.append(p.val)\n",
    "            p = p.next\n",
    "        res1.reverse()\n",
    "        q = l2\n",
    "        res2 = []\n",
    "        while q:\n",
    "            res2.append(q.val)\n",
    "            q = q.next\n",
    "        res2.reverse()\n",
    "\n",
    "        first = 0\n",
    "        for i in range(len(res1)):\n",
    "            first = first * 10 + res1[i]\n",
    "\n",
    "        second = 0\n",
    "        for i in range(len(res2)):\n",
    "            second = second * 10 + res2[i]\n",
    "\n",
    "        summ = first + second  # 807\n",
    "        if summ == 0:\n",
    "            return ListNode(0)\n",
    "        l3 = ListNode(0)\n",
    "        m = l3\n",
    "        while summ:   # 7 - 0 - 8\n",
    "            cnt = summ % 10\n",
    "            newnode = ListNode(cnt)\n",
    "            m.next = newnode\n",
    "            m = newnode\n",
    "            summ //= 10\n",
    "        return l3.next\n",
    "        # sum1 = 0\n",
    "        # sum2 = 0\n",
    "        # count = 0\n",
    "\n",
    "        # while(l1 != None):\n",
    "        #     x = l1.val\n",
    "        #     sum1 += x * 10**(count)\n",
    "        #     count += 1\n",
    "        #     l1 = l1.next\n",
    "\n",
    "        # count = 0\n",
    "        # while (l2 != None):\n",
    "        #     x = l2.val\n",
    "        #     sum2 += x * 10**(count)\n",
    "        #     count += 1\n",
    "        #     l2 = l2.next\n",
    "\n",
    "        # sum = sum1 + sum2\n",
    "\n",
    "        # d = sum % 10\n",
    "        # l3 = ListNode(d)\n",
    "        # sum = sum // 10\n",
    "        # a = l3\n",
    "        # while (sum != 0):\n",
    "        #     d = sum % 10\n",
    "        #     newNode = ListNode(d)\n",
    "        #     a.next = newNode\n",
    "        #     a = newNode\n",
    "        #     sum = sum // 10\n",
    "\n",
    "        # return l3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        head = ListNode(l1.val + l2.val)\n",
    "        if head.val >= 10:\n",
    "            head.next = ListNode(1)\n",
    "            head.val -= 10 \n",
    "        current = head\n",
    "        while l1.next or l2.next:\n",
    "            if l1.next is None:\n",
    "                l2 = l2.next\n",
    "                if current.next is None:\n",
    "                    current.next = ListNode(l2.val)\n",
    "                else:\n",
    "                    current.next.val += (l2.val) \n",
    "                \n",
    "            elif l2.next is None:\n",
    "                l1 = l1.next\n",
    "                if current.next is None:\n",
    "                    current.next = ListNode(l1.val)\n",
    "                else:\n",
    "                    current.next.val += (l1.val) \n",
    "            else:\n",
    "                l1 = l1.next\n",
    "                l2 = l2.next\n",
    "                if current.next is None:\n",
    "                    current.next = ListNode(l1.val + l2.val)\n",
    "                else:\n",
    "                    current.next.val += l1.val + l2.val\n",
    "                \n",
    "            current = current.next\n",
    "            if current.val >= 10:\n",
    "                current.next = ListNode(1)\n",
    "                current.val -= 10 \n",
    "        return head"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        dummy = ListNode(-1) #虚拟头节点\n",
    "        cur = dummy #pointer to dummy (开始先对准dummy,结束直接输出dummy.next)\n",
    "        t = 0 #进位\n",
    "        while (l1 or l2 or t):\n",
    "            if l1:\n",
    "                t+= l1.val\n",
    "                l1 = l1.next\n",
    "            if l2:\n",
    "                t+=l2.val\n",
    "                l2 = l2.next\n",
    "            cur.next = ListNode(t%10)\n",
    "            #记得挪cur\n",
    "            cur = cur.next\n",
    "            t = t//10\n",
    "        return dummy.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "class ListNode:\n",
    "    def __init__(self, val=0, next=None):\n",
    "        self.val = val\n",
    "        self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        carry = 0\n",
    "        head = None\n",
    "        while( l1 or  l2):\n",
    "            n1, n2 = 0, 0\n",
    "            if (l1):\n",
    "                n1 = l1.val\n",
    "                l1 = l1.next\n",
    "            if l2:\n",
    "                n2 = l2.val\n",
    "                l2 = l2.next\n",
    "            sum = n1 + n2 + carry\n",
    "            sum, carry = sum%10, int(sum/10)\n",
    "            print(sum, carry)\n",
    "            if head is None:\n",
    "                head = ListNode(sum)\n",
    "                tail = head\n",
    "            else:\n",
    "                tail.next = ListNode(sum)\n",
    "                tail = tail.next\n",
    "        if carry > 0:\n",
    "            tail.next = ListNode(carry)\n",
    "        return head\n",
    "                \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        # 这个可以直接按照加法的进位思想\n",
    "        ans = p = ListNode(0)\n",
    "        s= 0\n",
    "        while l1 or l2 or s:\n",
    "            s += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "            p.next = ListNode(s%10)\n",
    "            p = p.next\n",
    "            s = s//10\n",
    "            l1 = l1.next if l1 else None\n",
    "            l2 = l2.next if l2 else None\n",
    "        return ans.next\n",
    "\n",
    "\n",
    "        # a = l1\n",
    "        # b= l2\n",
    "        # sum1 = 0\n",
    "        # sum2 = 0\n",
    "        # while a:\n",
    "        #     sum1 = a.val+sum1\n",
    "        #     a = a.next\n",
    "        # while b:\n",
    "        #     sum2 = b.val+sum2\n",
    "        #     b = b.next\n",
    "        # num = sum1 + sum2\n",
    "        # listsum = ListNode(0)\n",
    "        # listsumfor = listsum\n",
    "        # array = []\n",
    "        # while True:\n",
    "        #     array.append(num%10)\n",
    "        #     num = num//10\n",
    "        #     if num<10:\n",
    "        #         array.append(num)\n",
    "        #         break\n",
    "        # L = len(array)\n",
    "        # for i in range(1,L):\n",
    "        #     listsum.next= ListNode(array[L-i])\n",
    "        #     listsum = listsum.next\n",
    "        # return listsumfor.next\n",
    "   \n",
    "        \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, x):\n",
    "#         self.val = x\n",
    "#         self.next = None\n",
    "\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        i =0\n",
    "        x=0\n",
    "        while l1:\n",
    "            temp = l1.val\n",
    "            l1 = l1.next\n",
    "            x = x + temp*pow(10,i)\n",
    "            i = i + 1\n",
    "            \n",
    "        i=0\n",
    "        y=0\n",
    "        while l2:\n",
    "            temp = l2.val\n",
    "            l2 = l2.next\n",
    "            y = y + temp*pow(10,i)\n",
    "            i = i + 1\n",
    "        z = x + y\n",
    "        str_sum = str(z)\n",
    "        head = ListNode(None)\n",
    "        temp_node =ListNode(None)\n",
    "        for ch in str_sum[::-1]:\n",
    "            print(ch)\n",
    "            if not head.val:\n",
    "                head.val = ch\n",
    "                temp = head\n",
    "            else:\n",
    "                temp.next = ListNode(ch)\n",
    "                temp = temp.next\n",
    "        return head\n",
    "            \n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "        \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:\n",
    "        res = p = ListNode(None)\n",
    "        s = 0\n",
    "\n",
    "        while l1 or l2 or s != 0:\n",
    "            s += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "            p.next = ListNode(s % 10)\n",
    "            p = p.next\n",
    "\n",
    "            if l1:\n",
    "                l1 = l1.next\n",
    "\n",
    "            if l2:\n",
    "                l2 = l2.next\n",
    "\n",
    "            s //= 10\n",
    "        return res.next\n",
    "        # \"\"\"\n",
    "        # 方法2解题思路:\n",
    "        # 通过哑节点连接两节点相加之和, 再将结果连接\n",
    "        # \"\"\"\n",
    "        # # 创建哑节点\n",
    "        # res = p = ListNode(0)\n",
    "        # # 节点相加之和\n",
    "        # s = 0\n",
    "\n",
    "        # # 循环条件: l1没遍历完或者l2没遍历完或者 `s // 10` 之后还有进位\n",
    "        # while l1 or l2 or s != 0:\n",
    "        #     # 节点相加\n",
    "        #     s += (l1.val if l1 else 0) + (l2.val if l2 else 0)\n",
    "        #     # 将哑变量连接新两数相加之后取余节点 (两数相加可能会>=10)\n",
    "        #     p.next = ListNode(s % 10)\n",
    "        #     # 指针指向当前的新节点\n",
    "        #     p = p.next\n",
    "\n",
    "        #     # 将l1和l2指针往后移动, 直到None\n",
    "        #     if l1:\n",
    "        #         l1 = l1.next\n",
    "\n",
    "        #     if l2:\n",
    "        #         l2 = l2.next\n",
    "\n",
    "        #     # 由于节点保存的是余数, 当两数相加>=10会有进位, 因此s需要除10取整, 用到后面一项相加\n",
    "        #     s //= 10\n",
    "        # # 返回哑变量后面的所有节点\n",
    "        # return res.next\n",
    "    #     \"\"\"\n",
    "    #     方法1解题思路:\n",
    "    #     由于数字是逆序存储于, 因此可以通过 `l.val * (10 ** digit)` 来获得正向的值\n",
    "    #     将两值相加后转为 `str` 类型后再遍历存储至节点\n",
    "    #     \"\"\"\n",
    "        \n",
    "    #     # 正向相加结果\n",
    "    #     forwardRes = str(self.getForwardRes(l1) + self.getForwardRes(l2))\n",
    "    #     # 结果倒转\n",
    "    #     backwardRes = forwardRes[::-1]\n",
    "        \n",
    "    #     n = len(backwardRes)\n",
    "    #     # 存储结果\n",
    "    #     res = [0] * n\n",
    "        \n",
    "    #     # 存储节点\n",
    "    #     for i in range(n):\n",
    "    #         res[i] = ListNode(int(backwardRes[i]))\n",
    "        \n",
    "    #     # 连接链表\n",
    "    #     for i in range(n-1):\n",
    "    #         res[i].next = res[i+1]\n",
    "        \n",
    "    #     return res[0]\n",
    "    # def getForwardRes(self, l):\n",
    "    #     \"\"\"\n",
    "    #     方法1的辅助函数, 用于获得正向链表节点结果\n",
    "    #     \"\"\"\n",
    "    #     # 结果值保存\n",
    "    #     res = 0\n",
    "    #     # 位数\n",
    "    #     digit = 0\n",
    "\n",
    "    #     # 遍历链表计算正向结果\n",
    "    #     while True:\n",
    "    #         res += (l.val) * (10 ** digit)\n",
    "    #         digit += 1\n",
    "    #         l = l.next\n",
    "    #         if not l:\n",
    "    #             break\n",
    "\n",
    "    #     return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        list1,list2 = [],[]\n",
    "        dummy_head = cur = ListNode()\n",
    "        while l1:\n",
    "            list1.insert(0,str(l1.val))\n",
    "            l1 = l1.next\n",
    "        while l2:\n",
    "            list2.insert(0,str(l2.val))\n",
    "            l2 = l2.next\n",
    "        addNum = int(''.join(list1))+int(''.join(list2))\n",
    "        addNum = list(str(addNum))\n",
    "        for i in range(len(addNum)):\n",
    "            addNum[i] = int(addNum[i])\n",
    "        for i in reversed(addNum):\n",
    "            node = ListNode(i)\n",
    "            cur.next = node\n",
    "            cur = cur.next\n",
    "        return dummy_head.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution(object):\n",
    "    def addTwoNumbers(self, l1, l2):\n",
    "        if not l1:\n",
    "            return l2\n",
    "        elif not l2:\n",
    "            return l1\n",
    "        sum = l1.val+l2.val\n",
    "        if sum > 9:\n",
    "            return ListNode(sum-10, self.addTwoNumbers(ListNode(1, None), self.addTwoNumbers(l1.next, l2.next)))\n",
    "        else:\n",
    "            return ListNode(sum, self.addTwoNumbers(l1.next, l2.next))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        len1=0\n",
    "        len2=0\n",
    "        l3=l1\n",
    "        while l3 is not None:\n",
    "            len1+=1\n",
    "            l3=l3.next\n",
    "        l3=l2   \n",
    "        while l3 is not None:\n",
    "            len2+=1\n",
    "            l3=l3.next\n",
    "        if len1>=len2:\n",
    "            l3=l1\n",
    "            flag=0\n",
    "            while l3 is not None:\n",
    "                if l2 is not None:\n",
    "                    l3.val=l2.val+l3.val+flag\n",
    "                else:\n",
    "                    l3.val+=flag\n",
    "                if l3.val>=10:\n",
    "                    l3.val-=10\n",
    "                    flag=1\n",
    "                    if l3.next==None:\n",
    "                        node=ListNode(len1)\n",
    "                        node.val=0\n",
    "                        l3.next=node\n",
    "                else:\n",
    "                    flag=0\n",
    "                l3=l3.next\n",
    "                if l2 is not None:\n",
    "                    l2=l2.next\n",
    "                \n",
    "                \n",
    "        else:\n",
    "            l3=l2\n",
    "            flag=0\n",
    "            while l3 is not None:\n",
    "                if l1 is not None:\n",
    "                    l3.val=l1.val+l3.val+flag\n",
    "                else:\n",
    "                    l3.val+=flag\n",
    "                if l3.val>=10:\n",
    "                    l3.val-=10\n",
    "                    flag=1\n",
    "                    if l3.next==None:\n",
    "                        node=ListNode(len2)\n",
    "                        node.val=0\n",
    "                        l3.next=node\n",
    "                else:\n",
    "                    flag=0\n",
    "                l3=l3.next\n",
    "                if l1 is not None:\n",
    "                    l1=l1.next\n",
    "\n",
    "        if len1>=len2:\n",
    "            return l1\n",
    "        else:\n",
    "            return l2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        head = ListNode()\n",
    "        head.val = l1.val + l2.val\n",
    "        carry = 1 if head.val > 9 else 0\n",
    "        head.val = head.val % 10\n",
    "        l1 = l1.next\n",
    "        l2 = l2.next\n",
    "        node = head\n",
    "\n",
    "        while l1 or l2:\n",
    "            l1n = l1.val if l1 is not None else 0\n",
    "            l2n = l2.val if l2 is not None else 0\n",
    "            node.next = ListNode()\n",
    "            node = node.next\n",
    "            node.val = l1n + l2n + carry\n",
    "            print(str(carry) + \" \" + str(node.val))\n",
    "            carry = 1 if node.val > 9 else 0\n",
    "            node.val = node.val % 10\n",
    "            l1 = l1.next if l1 is not None else None\n",
    "            l2 = l2.next if l2 is not None else None\n",
    "        if carry:\n",
    "            node.next = ListNode()\n",
    "            node = node.next\n",
    "            node.val = 1\n",
    "\n",
    "        return head\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        ans = ListNode()\n",
    "        cur = ans\n",
    "        carry = 0\n",
    "        while l1 or l2 or carry:\n",
    "            s = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry\n",
    "            carry, val = divmod(s, 10)\n",
    "            cur.next = ListNode(val)\n",
    "            cur = cur.next\n",
    "            l1 = l1.next if l1 else None\n",
    "            l2 = l2.next if l2 else None\n",
    "        return ans.next\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        ans_head = ListNode()\n",
    "        node1 = ans_head\n",
    "        flag = 0\n",
    "        while l1 != None or l2 != None:\n",
    "            if l1 == None:\n",
    "                node2 = ListNode((l2.val + flag) % 10)\n",
    "                flag = int((l2.val + flag) / 10)\n",
    "                l2 = l2.next\n",
    "            elif l2 == None:\n",
    "                node2 = ListNode((l1.val + flag) % 10)\n",
    "                flag = int((l1.val + flag) / 10)\n",
    "                l1 = l1.next\n",
    "            else:\n",
    "                node2 = ListNode((l1.val + l2.val + flag) % 10)\n",
    "                flag = int((l1.val + l2.val + flag) / 10)\n",
    "                l1 = l1.next\n",
    "                l2 = l2.next\n",
    "            node1.next = node2\n",
    "            node1 = node2\n",
    "        if flag:\n",
    "            node1.next = ListNode(1)\n",
    "        return ans_head.next"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        \n",
    "        carry = 0\n",
    "        preHead = ListNode(0)\n",
    "        curr = preHead\n",
    "\n",
    "        while l1 or l2 or carry:\n",
    "            val1 = l1.val if l1 else 0\n",
    "            val2 = l2.val if l2 else 0\n",
    "            carry, out = divmod(val1 + val2 + carry, 10)\n",
    "\n",
    "            curr.next = ListNode(out)\n",
    "            curr = curr.next\n",
    "\n",
    "            l1 = l1.next if l1 else None\n",
    "            l2 = l2.next if l2 else None\n",
    "        return preHead.next\n",
    "        # carry = 0\n",
    "        # preHead = ListNode(0)\n",
    "        # current = preHead\n",
    "\n",
    "        # while l1 or l2 or carry:\n",
    "        #     val1 = l1.val if l1 else 0\n",
    "        #     val2 = l2.val if l2 else 0\n",
    "        #     carry, out = divmod(val1 + val2 + carry, 10)\n",
    "            \n",
    "        #     current.next = ListNode(out)\n",
    "        #     current = current.next\n",
    "\n",
    "        #     l1 = l1.next if l1 else None\n",
    "        #     l2 = l2.next if l2 else None\n",
    "\n",
    "        # return preHead.next\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for singly-linked list.\n",
    "# class ListNode:\n",
    "#     def __init__(self, val=0, next=None):\n",
    "#         self.val = val\n",
    "#         self.next = next\n",
    "class Solution:\n",
    "    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:\n",
    "        return self.dfs(l1, l2, 0)\n",
    "    def dfs(self, l1, l2, carry):\n",
    "        if not l1 and not l2 and not carry:\n",
    "            return None\n",
    "        cur = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry\n",
    "        node = ListNode(cur % 10)\n",
    "        node.next = self.dfs(l1.next if l1 else None, l2.next if l2 else None, cur // 10)\n",
    "        return node"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for polynomial singly-linked list.\n",
    "class PolyNode:\n",
    "    def __init__(self, x=0, y=0, next=None):\n",
    "        self.coefficient = x\n",
    "        self.power = y\n",
    "        self.next = next\n",
    "\n",
    "class Solution:\n",
    "    def addPoly(self, poly1: 'PolyNode', poly2: 'PolyNode') -> 'PolyNode':\n",
    "\n",
    "        head=PolyNode()\n",
    "        node=head\n",
    "\n",
    "        while poly1!=None and poly2!=None:\n",
    "            if poly1.power>poly2.power:\n",
    "                node.next=poly1\n",
    "                poly1=poly1.next\n",
    "                node=node.next\n",
    "            elif poly1.power<poly2.power:\n",
    "                node.next=poly2\n",
    "                poly2=poly2.next\n",
    "                node=node.next\n",
    "            else:\n",
    "                n=poly1.coefficient+poly2.coefficient\n",
    "                if n!=0:\n",
    "                    poly1.coefficient=n\n",
    "                    node.next=poly1\n",
    "                    poly1=poly1.next\n",
    "                    poly2=poly2.next\n",
    "                    node=node.next\n",
    "                else:\n",
    "                    poly1=poly1.next\n",
    "                    poly2=poly2.next\n",
    "\n",
    "\n",
    "        if poly1:\n",
    "            node.next=poly1\n",
    "        elif poly2:\n",
    "            node.next=poly2\n",
    "        else:\n",
    "            node.next=None\n",
    "\n",
    "        return head.next\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for polynomial singly-linked list.\n",
    "# class PolyNode:\n",
    "#     def __init__(self, x=0, y=0, next=None):\n",
    "#         self.coefficient = x\n",
    "#         self.power = y\n",
    "#         self.next = next\n",
    "\n",
    "class Solution:\n",
    "    def addPoly(self, poly1: 'PolyNode', poly2: 'PolyNode') -> 'PolyNode':\n",
    "        if not poly1 and not poly2:\n",
    "            return None\n",
    "        if not poly1:\n",
    "            return poly2\n",
    "        if not poly2:\n",
    "            return poly1\n",
    "        dummy=PolyNode(0)\n",
    "        cur=dummy\n",
    "        while poly1 and poly2:\n",
    "            if poly1.power>poly2.power:\n",
    "                cur.next=poly1\n",
    "                poly1=poly1.next\n",
    "                cur=cur.next\n",
    "            elif poly2.power>poly1.power:\n",
    "                cur.next=poly2\n",
    "                poly2=poly2.next\n",
    "                cur=cur.next\n",
    "            else:\n",
    "                sum=poly1.coefficient+poly2.coefficient\n",
    "                \n",
    "                if sum!=0:\n",
    "                    cur.next=PolyNode(sum,poly1.power)\n",
    "                    cur=cur.next\n",
    "                poly1=poly1.next\n",
    "                poly2=poly2.next                \n",
    "                \n",
    "                        \n",
    "        if not poly1:\n",
    "            cur.next=poly2\n",
    "        if not poly2:\n",
    "            cur.next=poly1\n",
    "        return dummy.next\n",
    "\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for polynomial singly-linked list.\n",
    "# class PolyNode:\n",
    "#     def __init__(self, x=0, y=0, next=None):\n",
    "#         self.coefficient = x\n",
    "#         self.power = y\n",
    "#         self.next = next\n",
    "\n",
    "class Solution:\n",
    "    def addPoly(self, poly1: 'PolyNode', poly2: 'PolyNode') -> 'PolyNode':\n",
    "        dummy = cur = PolyNode()\n",
    "        while poly1 and poly2:\n",
    "            if poly1.power > poly2.power:\n",
    "                cur.next = poly1\n",
    "                poly1 = poly1.next\n",
    "                cur = cur.next\n",
    "            elif poly1.power < poly2.power:\n",
    "                cur.next = poly2\n",
    "                poly2 = poly2.next\n",
    "                cur = cur.next\n",
    "            else:\n",
    "                if (coe := poly1.coefficient + poly2.coefficient) != 0:\n",
    "                    cur.next = PolyNode(coe, poly1.power)\n",
    "                    cur = cur.next \n",
    "                poly1 = poly1.next \n",
    "                poly2 = poly2.next\n",
    "            cur.next = None\n",
    "                \n",
    "        if poly1:\n",
    "            cur.next = poly1\n",
    "        elif poly2:\n",
    "            cur.next = poly2\n",
    "\n",
    "        return dummy.next\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for polynomial singly-linked list.\n",
    "# class PolyNode:\n",
    "#     def __init__(self, x=0, y=0, next=None):\n",
    "#         self.coefficient = x\n",
    "#         self.power = y\n",
    "#         self.next = next\n",
    "\n",
    "class Solution:\n",
    "    def addPoly(self, poly1: 'PolyNode', poly2: 'PolyNode') -> 'PolyNode':\n",
    "\n",
    "        ans = PolyNode(-1, -1)\n",
    "        cur = ans\n",
    "        while poly1 and poly2:\n",
    "            if poly1.power > poly2.power:\n",
    "                tmp = poly1.next\n",
    "                poly1.next = None\n",
    "                cur.next = poly1\n",
    "                cur = cur.next\n",
    "                poly1 = tmp\n",
    "            elif poly1.power < poly2.power:\n",
    "                tmp = poly2.next\n",
    "                poly2.next = None\n",
    "                cur.next = poly2\n",
    "                cur = cur.next\n",
    "                poly2 = tmp\n",
    "            else:\n",
    "                if poly1.coefficient + poly2.coefficient:\n",
    "                    cur.next = PolyNode(poly1.coefficient + poly2.coefficient, poly1.power)\n",
    "                    cur = cur.next\n",
    "                poly1 = poly1.next\n",
    "                poly2 = poly2.next\n",
    "\n",
    "        if poly1:\n",
    "            cur.next = poly1\n",
    "        if poly2:\n",
    "            cur.next = poly2\n",
    "        return ans.next\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for polynomial singly-linked list.\n",
    "# class PolyNode:\n",
    "#     def __init__(self, x=0, y=0, next=None):\n",
    "#         self.coefficient = x\n",
    "#         self.power = y\n",
    "#         self.next = next\n",
    "\n",
    "class Solution:\n",
    "    def addPoly(self, poly1: 'PolyNode', poly2: 'PolyNode') -> 'PolyNode':\n",
    "        dic={}\n",
    "        while poly1:\n",
    "            dic[poly1.power]=poly1.coefficient\n",
    "            poly1=poly1.next\n",
    "        while poly2:\n",
    "            if poly2.power not in dic:\n",
    "                dic[poly2.power]=poly2.coefficient\n",
    "            else:\n",
    "                dic[poly2.power]+=poly2.coefficient\n",
    "            poly2=poly2.next\n",
    "        keys=sorted(list(dic.keys()),reverse=True)\n",
    "        head=PolyNode()\n",
    "        current=head\n",
    "        for i in keys:\n",
    "            if dic[i]!=0:\n",
    "                current.next=PolyNode(dic[i],i)\n",
    "                current=current.next\n",
    "        return head.next\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# Definition for polynomial singly-linked list.\n",
    "# class PolyNode:\n",
    "#     def __init__(self, x=0, y=0, next=None):\n",
    "#         self.coefficient = x\n",
    "#         self.power = y\n",
    "#         self.next = next\n",
    "\n",
    "class Solution:\n",
    "    def addPoly(self, poly1: 'PolyNode', poly2: 'PolyNode') -> 'PolyNode':\n",
    "        dic = defaultdict(int)\n",
    "        while poly1:\n",
    "            dic[poly1.power] += poly1.coefficient\n",
    "            poly1 = poly1.next\n",
    "        while poly2:\n",
    "            dic[poly2.power] += poly2.coefficient\n",
    "            poly2 = poly2.next\n",
    "        arr = []\n",
    "        for k, v in dic.items():\n",
    "            if v:\n",
    "                arr.append((k, v))\n",
    "        arr.sort(reverse=True)\n",
    "\n",
    "        dummy = PolyNode()\n",
    "        curr = dummy\n",
    "        for k, v in arr:\n",
    "            node = PolyNode(v, k)\n",
    "            curr.next = node\n",
    "            curr = node\n",
    "        return dummy.next\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self ,x ,y):\n",
    "        c = x + y\n",
    "        return c    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        if b == 0:\n",
    "            return a\n",
    "        return add(a^b,(a&b)<<1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        lst = []\n",
    "        lst.append(a)\n",
    "        lst.append(b)\n",
    "        return sum(lst)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        A = []\n",
    "        A.append(a)\n",
    "        A.append(b)\n",
    "        return sum(A)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        mask1,mask2,mask3 = 4294967296,2147483648,2147483647  \n",
    "        # a %=mask1\n",
    "        # b %=mask1\n",
    "        while b!=0:\n",
    "            a,b = (a^b)%mask1,((a&b)<<1)%mask1\n",
    "        return ~((a ^ mask2) ^ mask3) if a&mask2 else a\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        nums = [a,b]\n",
    "        sums = sum(nums)\n",
    "        return sums"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        s=a+b\n",
    "        return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MASK1 = 4294967296  # 2^32\n",
    "MASK2 = 2147483648  # 2^31\n",
    "MASK3 = 2147483647  # 2^31-1\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        a %= MASK1\n",
    "        b %= MASK1\n",
    "        while b != 0:\n",
    "            carry = ((a & b) << 1) % MASK1\n",
    "            a = (a ^ b) % MASK1\n",
    "            b = carry\n",
    "        if a & MASK2:  # 负数\n",
    "            return ~((a ^ MASK2) ^ MASK3)\n",
    "        else:  # 正数\n",
    "            return a\n",
    "\n",
    "# 作者：力扣官方题解\n",
    "# 链接：https://leetcode.cn/problems/add-without-plus-lcci/solutions/1718025/bu-yong-jia-hao-de-jia-fa-by-leetcode-so-pp8a/\n",
    "# 来源：力扣（LeetCode）\n",
    "# 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return sum([a,b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(Self, x, y):\n",
    "        z = (x ^ y) + ((x & y) << 1)\n",
    "        return z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(Self, x, y):\n",
    "        return (x^y) + ((x&y)<<1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        x=0xffffffff\n",
    "        a&=x\n",
    "        b&=x\n",
    "\n",
    "        while b!=0:\n",
    "            a,b=(a^b),(a&b)<<1&(x)\n",
    "\n",
    "        return a if a<=0x7fffffff else ~(a^x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        while b != 0:\n",
    "            carry = ((a & b) << 1) & 0xffffffff\n",
    "            a = (a ^ b) & 0xffffffff\n",
    "            b = carry\n",
    "        return a if a <= 0x7fffffff else ~(a ^ 0xffffffff)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        c=[a,b]\n",
    "        return sum(c)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        x = 0xffffffff\n",
    "\n",
    "        a, b = a & x, b & x\n",
    "        while b:\n",
    "            c = a & b \n",
    "            a = a ^ b\n",
    "            b = (c<<1) & x\n",
    "        return a if a <= 0x7fffffff else ~a^x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return sum([a, b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "### my:异或，与，运算错误 a=-1,b=2 \n",
    "# class Solution:\n",
    "#     def add(self, a: int, b: int) -> int:\n",
    "#         # a,b=a&0x7FFFFFFF,b&0x7FFFFFFF\n",
    "#         a,b=a^b,(a&b)<<1\n",
    "#         while a>2**-31 and a<=2**31-1 and b:\n",
    "#             a,b=a^b,(a&b)<<1\n",
    "#         return a\n",
    "\n",
    "### 官解：位运算\n",
    "class Solution:\n",
    "    def add(self,a,b):\n",
    "        msk1=2**32\n",
    "        msk2=2**31\n",
    "        msk3=2**31-1\n",
    "        ### 1.保证a,b都是32位以内的数\n",
    "        a,b=a%msk1,b%msk1\n",
    "        ### 2.位运算，求加的结果\n",
    "        while b:\n",
    "            a,b=(a^b)%msk1,((a&b)<<1)%msk1 ### 重要：始终保持32位之内\n",
    "        ### 3.根据正负翻译相加结果a\n",
    "        if a<msk2:\n",
    "            return a\n",
    "        else:### 负数的补码（翻译成负数）\n",
    "            return  ~((a^msk2)^msk3) #\n",
    "            ## c=((a^msk2)^msk3)等价于把负数补码的最高符号位去掉，且逐位取反\n",
    "            ## ~c：等价于非符号位逐位取反后，再添加并识别最高符号位，使得a的最高符号位被识别出来（识别出最高位为符号位的负数补码形式）\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        a &= 0xFFFFFFFF\n",
    "        b &= 0xFFFFFFFF\n",
    "        while b:\n",
    "            carry = a & b\n",
    "            a ^= b\n",
    "            b = ((carry) << 1) & 0xFFFFFFFF\n",
    "        return a if a < 0x80000000 else ~(a^0xFFFFFFFF)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        a&=0xFFFFFFFF\n",
    "        b&=0xFFFFFFFF\n",
    "        while b!=0:\n",
    "            carry=a&b\n",
    "            a^=b\n",
    "            b=(carry<<1)&0xFFFFFFFF\n",
    "        return a if a<0x80000000 else ~(a^0xFFFFFFFF)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        mask1,mask2,mask3 = 4294967296,2147483648,2147483647  \n",
    "        while b!=0:\n",
    "            a,b = (a^b)%mask1,((a&b)<<1)%mask1\n",
    "        return ~((a ^ mask2) ^ mask3) if a&mask2 else a\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        x = 0xffffffff\n",
    "\n",
    "        a, b = a & x, b & x\n",
    "        while b:\n",
    "            c = a & b \n",
    "            a = a ^ b\n",
    "            b = (c<<1) & x\n",
    "        return a if a <= 0x7fffffff else ~(a^x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        a &= 0xFFFFFFFF\n",
    "        b &= 0xFFFFFFFF\n",
    "        while b != 0:\n",
    "            carry = a & b\n",
    "            a ^= b\n",
    "            b = ((carry) << 1) & 0xFFFFFFFF\n",
    "        return a if a < 0x80000000 else ~(a^0xFFFFFFFF)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(Self, x, y):\n",
    "        return sum([x,y])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return(sum([a,b]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        x = 0xffffffff\n",
    "\n",
    "        a, b = a & x, b & x\n",
    "        while b:\n",
    "            c = a & b \n",
    "            a = a ^ b\n",
    "            b = (c<<1) & x\n",
    "        return a if a <= 0x7fffffff else ~(a^x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        num=0xffffffff\n",
    "        a,b=a&num,b&num\n",
    "        while b!=0:\n",
    "            c=a&b\n",
    "            a=a^b\n",
    "            b=(c<<1)&num\n",
    "        return a if a<=0x7fffffff else ~(a^num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        # 加法需要处理位数相加后的进位和非进位的结果\n",
    "        # 非进位信息可以通过“异或运算”，位数相同为0，不同则为1\n",
    "        # 进位信息可以通过“与运算”\n",
    "        \n",
    "        # 循环：当再也不需要进位时加法结束\n",
    "        while b != 0:\n",
    "            # 临时结果：进位结果和不进位结果的异或运算即为加法\n",
    "            # 不进位加法（用于承接最终结果）\n",
    "            temp_res = b ^ a\n",
    "            # 进位加法（即与运算后再左移一位）\n",
    "            b = (a & b) << 1\n",
    "            # 这里的与运算用于处理负数\n",
    "            a = temp_res & 0xFFFFFFFF\n",
    "        return a if a >> 31 == 0 else a - 4294967296"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a.__add__(b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return sum([a,b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return sum([a,b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        a &= 0xFFFFFFFF\n",
    "        b &= 0xFFFFFFFF\n",
    "        while b != 0:\n",
    "            carry = a & b\n",
    "            a ^= b\n",
    "            b = ((carry) << 1) & 0xFFFFFFFF\n",
    "        return a if a < 0x80000000 else ~(a^0xFFFFFFFF)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MASK1 = 4294967296  # 2^32\n",
    "MASK2 = 2147483648  # 2^31\n",
    "MASK3 = 2147483647  # 2^31-1\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        a %= MASK1\n",
    "        b %= MASK1\n",
    "        while b != 0:\n",
    "            carry = ((a & b) << 1) % MASK1\n",
    "            a = (a ^ b) % MASK1\n",
    "            b = carry\n",
    "        if a & MASK2:  # 负数\n",
    "            return ~((a ^ MASK2) ^ MASK3)\n",
    "        else:  # 正数\n",
    "            return a\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        MASK1 = 4294967296  # 2^32\n",
    "        MASK2 = 2147483648  # 2^31\n",
    "        MASK3 = 2147483647  # 2^31-1\n",
    "        a %= MASK1\n",
    "        b %= MASK1\n",
    "        while b != 0:\n",
    "            carry = ((a & b) << 1) % MASK1\n",
    "            a = (a ^ b) % MASK1\n",
    "            b = carry\n",
    "        if a & MASK2:  # 负数\n",
    "            return ~(a ^ MASK2) ^ MASK3\n",
    "        else:  # 正数\n",
    "            return a\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return (a^b) + ((a&b)<<1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return sum([a,b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MASK1 = 4294967296  # 2^32\n",
    "MASK2 = 2147483648  # 2^31\n",
    "MASK3 = 2147483647  # 2^31-1\n",
    "\n",
    "# class Solution:\n",
    "#     def add(self, a: int, b: int) -> int:\n",
    "#         a %= MASK1\n",
    "#         b %= MASK1\n",
    "#         while b != 0:\n",
    "#             carry = ((a & b) << 1) % MASK1\n",
    "#             a = (a ^ b) % MASK1\n",
    "#             b = carry\n",
    "#         if a & MASK2:  # 负数\n",
    "#             return ~((a ^ MASK2) ^ MASK3)\n",
    "#         else:  # 正数\n",
    "#             return a\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        a &= 0xFFFFFFFF\n",
    "        b &= 0xFFFFFFFF\n",
    "        # a %= MASK1\n",
    "        # b %= MASK1\n",
    "        print(a,b)\n",
    "        while b != 0:\n",
    "            carry = a&b\n",
    "            a ^= b\n",
    "            b = (carry<<1) & 0xFFFFFFFF\n",
    "            print(carry,a,b)\n",
    "        return a if a < 0x80000000 else ~(a^0xFFFFFFFF)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return sum([a,b])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        x = 0xffffffff\n",
    "        a = a & x\n",
    "        b = b & x \n",
    "\n",
    "        while b != 0: \n",
    "            c = a & b \n",
    "            a = a ^ b \n",
    "            b = (c << 1) & x \n",
    "        \n",
    "        if a <= 2**31-1:\n",
    "            return a \n",
    "        else: \n",
    "            return ~(a ^ x)\n",
    "        \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        mask1,mask2,mask3 = 4294967296,2147483648,2147483647  \n",
    "        a %=mask1\n",
    "        b %=mask1\n",
    "        while b!=0:\n",
    "            # tmp = ((a&b)<<1)%mask1\n",
    "            # a = (a^b)%mask1\n",
    "            # b = tmp\n",
    "            b,a, = ((a&b)<<1)%mask1,(a^b)%mask1\n",
    "        return ~((a ^ mask2) ^ mask3) if a&mask2 else a\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "\tdef add(self, a: int, b: int) -> int:\n",
    "\t\treturn a + b\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        c = -a\n",
    "        d = b-c\n",
    "        return d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        List = []\n",
    "        List.append(a)\n",
    "        List.append(b)\n",
    "        return sum(List)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        MASK = (1<<32) - 1\n",
    "        a &= MASK\n",
    "        b &= MASK\n",
    "        while a:\n",
    "            a, b = ((a&b) << 1) & MASK, (a^b) & MASK\n",
    "        \n",
    "        if b & (1<<31):\n",
    "            b -= (1<<32)\n",
    "        return b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MASK1 = 4294967296  # 2^32\n",
    "MASK2 = 2147483648  # 2^31\n",
    "MASK3 = 2147483647  # 2^31-1\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        num=0xffffffff\n",
    "        a,b=a&num,b&num\n",
    "        while b!=0:\n",
    "            c=a&b\n",
    "            a=a^b\n",
    "            b=(c<<1)&num\n",
    "        return a if a<=0x7fffffff else ~(a^num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        if b == 0:\n",
    "            return a\n",
    "        else:\n",
    "            return add((a ^ b),(a & b)<<1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "MASK1 = 4294967296  # 2^32\n",
    "MASK2 = 2147483648  # 2^31\n",
    "MASK3 = 2147483647  # 2^31-1\n",
    "\n",
    "# class Solution:\n",
    "#     def add(self, a: int, b: int) -> int:\n",
    "#         a %= MASK1\n",
    "#         b %= MASK1\n",
    "#         while b != 0:\n",
    "#             carry = ((a & b) << 1) % MASK1\n",
    "#             a = (a ^ b) % MASK1\n",
    "#             b = carry\n",
    "#         if a & MASK2:  # 负数\n",
    "#             return ~((a ^ MASK2) ^ MASK3)\n",
    "#         else:  # 正数\n",
    "#             return a\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        # a &= 0xffffffff\n",
    "        # b &= 0xffffffff\n",
    "        # print(0xFFFFFFFF,0xffffffff)\n",
    "        a %= MASK1\n",
    "        b %= MASK1\n",
    "        print(a,b)\n",
    "        while b != 0:\n",
    "            carry = a&b\n",
    "            a ^= b\n",
    "            b = (carry<<1) & 0xffffffff\n",
    "            print(carry,a,b)\n",
    "        return a if a < 0x80000000 else ~(a^0xFFFFFFFF)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        num=0xffffffff\n",
    "        a,b=a&num,b&num\n",
    "        while b!=0:\n",
    "            c=a&b\n",
    "            a=a^b\n",
    "            b=(c<<1)&num\n",
    "        return a if a<=0x7fffffff else ~(a^num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "### my:异或，与，运算错误 a=-1,b=2 \n",
    "# class Solution:\n",
    "#     def add(self, a: int, b: int) -> int:\n",
    "#         # a,b=a&0x7FFFFFFF,b&0x7FFFFFFF\n",
    "#         a,b=a^b,(a&b)<<1\n",
    "#         while a>2**-31 and a<=2**31-1 and b:\n",
    "#             a,b=a^b,(a&b)<<1\n",
    "#         return a\n",
    "\n",
    "class Solution:\n",
    "    def add(self,a,b):\n",
    "        msk1=2**32\n",
    "        msk2=2**31\n",
    "        msk3=2**31-1\n",
    "        ### 1.保证a,b都是32位以内的数\n",
    "        a,b=a%msk1,b%msk1\n",
    "        ### 2.位运算，求加的结果\n",
    "        while b:\n",
    "            a,b=(a^b)%msk1,((a&b)<<1)%msk1 ### 重要：始终保持32位之内\n",
    "        ### 3.根据正负翻译相加结果a\n",
    "        if a<msk2:\n",
    "            return a\n",
    "        else:### 负数的补码（翻译成负数）\n",
    "            return  ~((a^msk2)^msk3)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return(a+b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        return a+b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def add(self, a: int, b: int) -> int:\n",
    "        while b:\n",
    "            a &= 0xFFFFFFFF\n",
    "            b &= 0xFFFFFFFF\n",
    "            a, b = a ^ b, (a & b) << 1  # 每位相加结果、进位值\n",
    "        return a if a < 0x80000000 else ~(a ^ 0xFFFFFFFF)"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
